bash 循环遍历带空格的字符串数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12300599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loop through array of arrays of string with spaces
提问by A K
I'm trying to loop through an array that contains other arrays and these arrays consist of strings with spaces. The problem is that I can't seem to preserve the spacing in the string. The string with spaces are either divided into multiple items if I change IFS to \n or all the elements of the array are seen as 1 item if I leave IFS unchanged here's some sample code:
我试图遍历一个包含其他数组的数组,这些数组由带空格的字符串组成。问题是我似乎无法保留字符串中的间距。如果我将 IFS 更改为 \n,则带空格的字符串要么被分成多个项目,要么如果我保持 IFS 不变,则数组的所有元素都被视为 1 个项目,这里有一些示例代码:
#!/bin/sh
low1=("AA QQ" "BB LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)
for high_item in ${high[@]}
do
eval arrayz=${$high_item[@]}
#IFS=$'\n'
for item in $arrayz
do
echo $item
done
done
Output:
输出:
AA QQ BB LL CC DD EE FF
As you can see the elements "AA QQ" and "BB LL" have been split.
如您所见,元素“AA QQ”和“BB LL”已被拆分。
If I uncomment the line that sets IFSto \nI get the following:
如果我取消注释设置IFS为的行,\n我会得到以下信息:
AA QQ BB LL CC DD EE FF
Now "AA QQ" and "BB LL" are concatenated!
现在“AA QQ”和“BB LL”连接起来了!
Is there anyway I can preserve these elements just as they original are...I need the output to look like that:
无论如何我可以保留这些元素,就像它们原来的一样......我需要输出看起来像这样:
AA QQ BB LL CC DD EE FF
回答by Micha? Górny
I think you meant that the output should look like:
我认为你的意思是输出应该是这样的:
AA QQ
BB LL
CC
DD
EE
FF
i.e.:
IE:
${low1[0]}
${low1[1]}
${low2[0]}
${low2[1]}
${low3[0]}
${low3[1]}
This could be accomplished using:
这可以使用以下方法完成:
#!/bin/bash
low1=("AA QQ" "BB LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)
for high_item in ${high[@]}
do
x="${high_item}[@]" # -> "low1[@]"
arrays=( "${!x}" )
#IFS=$'\n'
for item in "${arrays[@]}"
do
echo "$item"
done
done
And pleasealways use #!/bin/bashfor bash scripts.
并且请始终#!/bin/bash用于 bash 脚本。
Explanation: ${!x}is indirect variable expansion. It evaluates to the value of variable with a name contained in $x.
解释:${!x}是间接变量展开。它的计算结果是名称包含在 中的变量的值$x。
For our needs, xneeds to have the [@]suffix for array expansion as well. Especially note that it is x=${high_item}[@]and notx=${high_item[@]}.
对于我们的需要,还x需要有[@]数组扩展的后缀。特别注意它是x=${high_item}[@]和不是x=${high_item[@]}。
And you have toevaluate it in array context; otherwise, it wouldn't work as expected (if you do arrays=${!x}).
你必须在数组上下文中评估它;否则,它不会按预期工作(如果你这样做arrays=${!x})。
Ah, and as final note: IFSdoesn't make any difference here. As long as you are working on quoted arrays, IFSdoesn't come into play.
啊,最后一点:IFS这里没有任何区别。只要您正在处理引用数组,IFS就不会起作用。
回答by chepner
Replace evalwith indirect parameter expansion, and you'll get what I think you want (although it doesn't match your current given output:
替换eval为间接参数扩展,您将得到我认为您想要的(尽管它与您当前的给定输出不匹配:
for high_item in "${high[@]}"
do
arrayz="$high_item[@]"
# arrayz is just a string like "low1[@]"
for item in "${!arrayz}"
do
echo $item
done
done
Note the need to quote the array expansion in the inner loop to preserve the whitespace in elements of low1.
请注意需要在内循环中引用数组扩展以保留low1.

