gpt4 book ai didi

arrays - bash 字符串引用多字参数到数组

转载 作者:行者123 更新时间:2023-11-29 08:57:45 25 4
gpt4 key购买 nike

问题:

在 bash 脚本中,将包含围绕多个单词的文字引号的字符串转换为具有与解析参数相同结果的数组的最佳方法是什么?

争议:

存在许多问题都采用规避策略来避免问题而不是找到解决方案,这个问题提出了以下论点,并希望鼓励读者关注论点,如果你愿意,请参与挑战找到最优解。

提出的论点:

  1. 虽然在许多情况下应该避免这种模式,因为存在更适合的替代解决方案,但作者认为有效的用例仍然存在。这个问题将尝试产生一个这样的用例,但不会声称其可行性只是它是一个可以想象的场景,可能会出现在现实世界的情况中。
  2. 您必须找到满足要求的最佳解决方案。该用例是专门为其实际应用选择的。您可能不同意所做的决定,但没有任务只是为了提供解决方案而发表意见。
  3. 在不修改输入或运输选择的情况下满足要求。两者都特别选择了真实世界的场景,以捍卫这些部分不受您控制的说法。
  4. 特定问题没有答案,这个问题旨在解决这个问题。如果您倾向于避免这种模式,那么只需回避这个问题,但如果您认为自己已经准备好迎接挑战,那么让我们看看您将如何解决这个问题。

有效用例:

将当前使用的现有脚本转换为通过命名管道或类似流接收参数。为了尽量减少对开发人员控制之外的无数脚本的影响,决定不更改界面。现有脚本必须能够像以前一样通过新的流实现传递相同的参数。

现有实现:

$ ./string2array arg1 arg2 arg3
args=(
[0]="arg1"
[1]="arg2"
[2]="arg3"
)

所需更改:

$ echo "arg1 arg2 arg3" | ./string2array
args=(
[0]="arg1"
[1]="arg2"
[2]="arg3"
)

问题:

正如 Bash and Double-Quotes passing to argv 指出的那样文字引号未按预期进行解析。

此工作台脚本可用于测试各种解决方案,它处理传输并制定可衡量的响应。建议您关注以字符串作为参数的解决方案脚本,并且您应该将 $args 变量填充为数组。

string2array 工作台脚本:

#!/usr/bin/env bash
#string2arry

args=()

function inspect() {
local inspct=$(declare -p args)
inspct=${inspct//\[/\\n\\t[}; inspct=${inspct//\'/}; inspct="${inspct:0:-1}\n)"
echo -e ${inspct#*-a }
}

while read -r; do
# source the solution to turn $REPLY in $args array
source $1 "${REPLY}"
inspect
done

标准解决方案 - 失败

将字符串转换为以空格分隔的单词数组的解决方案适用于我们上面的第一个示例:

#solution1

args=($@)

不希望的结果

不幸的是,标准解决方案对引用的多词参数产生了不希望的结果:

$ echo 'arg1 "multi arg 2" arg3' | ./string2array solution1
args=(
[0]="arg1"
[1]="\"multi"
[2]="arg"
[3]="2\""
[4]="arg3"
)

挑战:

使用工作台脚本提供一个解决方案片段,该片段将为收到的参数生成以下结果。

期望的结果:

$ echo 'arg1 "multi arg 2" arg3' | ./string2array solution-xyz
args=(
[0]="arg1"
[1]="multi arg 2"
[2]="arg3"
)

该解决方案应在各个方面都与标准参数解析兼容。以下单元测试应该通过提供的解决方案。如果您能想到单元测试中目前缺少的任何内容,请发表评论,我们可以对其进行更新。

需求的单元测试

更新测试简化并包括 Johnathan Leffer 测试

#!/usr/bin/env bash
#test_string2array
solution=$1
function test() {
cmd="echo \"${1}\" | ./string2array $solution"
echo "$ ${cmd}"
echo ${1} | ./string2array $solution > /tmp/t
cat /tmp/t
echo -n "Result : "
[[ $(cat /tmp/t|wc -l) -eq 7 ]] && echo "PASSED!" || echo "FAILED!"
}

echo 1. Testing single args
test 'arg1 arg2 arg3 arg4 arg5'
echo
echo 2. Testing multi args \" quoted
test 'arg1 "multi arg 2" arg3 "a r g 4" arg5'
echo
echo 3 Testing multi args \' quoted
test "arg1 'multi arg 2' arg3 'a r g 4' arg5"
echo
echo 4 Johnathan Leffer test
test "He said, \"Don't do that!\" but \"they didn't listen.\""

最佳答案

内置的declare 似乎做你想做的事;在我的测试中,您的 inspect 函数似乎无法正确测试所有输入:

# solution3
declare -a "args=($1)"

然后

$ echo "arg1 'arg2a arg2b' arg3" | while read -r; do
> source solution3 "${REPLY}"
> for arg in "${args[@]}"; do
> echo "Arg $((++i)): $arg"
> done
> done
Arg 1: arg1
Arg 2: arg2a arg2b
Arg 3: arg3

关于arrays - bash 字符串引用多字参数到数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22291816/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com