使用命令输出中的带引号的条目在Bash中创建数组

时间:2015-03-06 15:01:42

标签: arrays bash stdout quoting

我在从标准输出中形成bash数组时遇到问题。我把它归结为这个最小的例子:

~$ a=($(echo '1 2 3 "foo bar"'))
~$ echo ${a[0]}
1
~$ echo ${a[1]}
2
~$ echo ${a[2]}
3
~$ echo ${a[3]}
"foo
~$ echo ${a[4]}
bar"

我相信正在发生的事情是"foobar"被视为标准输出中的单独项目,但目标是将这些项目合并为数组中的项目。

显然,我可以编写一个小循环来将这些术语合并为一个,但我想知道有更优雅的解决方案吗?

编辑:在我的代码中代替echo '1 2 3 "foo bar"'的内容相当复杂,但关键是我需要从这个未知的标准输出中形成一个数组形式

3 个答案:

答案 0 :(得分:6)

xargs会识别引号

mapfile -t a <<<"$(echo '1 2 3  "foo bar"' | xargs -n 1)"
printf "%s\n" "${a[@]}"
1
2
3
foo bar

答案 1 :(得分:4)

过程替换不仅是不必要的,而且是直接有害的。你想要

a=(1 2 3 "foo bar")

如果您知道预期的项目数量,可以

read a b c d <<<$(echo '1 2 3 "foo bar"')

最终,我猜你无法逃脱eval

答案 2 :(得分:1)

您可以替换

  

此表单的某些未知标准输出

进入并通过mapfile命令将行读入数组。

例如,这可以通过perl完成,它的核心模块如下:

some_command() { echo '1 2 3 "foo bar"'; }

echo "output from some_command"
some_command

echo
echo "Parsed into array"
mapfile -t array < <(some_command | perl -MText::ParseWords -lnE 'say for shellwords($_)')
printf '=%s=\n' "${array[@]}"

打印什么

output from some_command
1 2 3 "foo bar"

Parsed into array
=1=
=2=
=3=
=foo bar=

编辑:刚认出1_CR的答案。

mapfile -t array < <(some_command | xargs -n 1)

好多了;)