Arrays 在Bash中使用命令输出中的引用项创建数组

Arrays 在Bash中使用命令输出中的引用项创建数组,arrays,bash,stdout,quoting,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" 我相信现在的情况是,“foo和bar”在标准输出中被视为独立的项,但目标是将这些项合并到一个数组中 显然,我可以编写一个小循环来将这些术语合并为一个,但我想知道是否有一个更

从标准输出生成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"
我相信现在的情况是,
“foo
bar”
在标准输出中被视为独立的项,但目标是将这些项合并到一个数组中

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


编辑:在我的代码中取代
echo'1 2 3“foo bar”
的是相当复杂的,但问题是我需要从这种形式的未知标准输出中形成一个数组

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

a=(1 2 3 "foo bar")
如果你知道需要多少物品,你可以做

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

readabcd
xargs

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

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

进入,并通过
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[@]}"
编辑:刚刚识别出1_CR的答案

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

mapfile-t array<如果没有一两个严重的混乱,这是不会发生的。您可以更改输出格式吗?如果您将每个数组条目放在单独的一行上,那会容易得多。
eval a=($(echo'1 2 3“foo bar”)
如果没有
eval
,您就无法完成它,这是危险的,除非您能够绝对保证您的输入是什么(否则这是一个巨大的安全漏洞)。我理解这将如何创建一个具有正确术语的数组,但是代替
echo'123foobar'
的是一个更复杂的命令的输出。我不确定这是否解决了问题,因为我需要从标准输出创建一个数组。为了提供一些上下文,既然OP已经阐明了他的意图:(a)第一个代码片段仅适用于创建具有已知数量元素的数组(从文本或特定于元素的扩展)。(b) 第二个代码段仅在捕获的输出末尾有1个带引号的标记时有效(该标记的前导和尾随空格将被修剪)。(c) answer提供了一个基于
xarg
的通用解决方案,该解决方案能够识别字符串文本中带引号的标记。简直太棒了+10如果我可以:)非常好-不知道
xargs
识别嵌入字符串文字中的带引号的标记(可用于单引号和双引号)。对于Bash3.x用户(例如,在OSX上):
IFS=$'\n'read-d'-ra a
mapfile
bash4+。否则——有没有理由使用
没关系,回答了我自己的问题。我以为
echo'123foobar'| xargs-n1 | mapfile-ta
起作用了,但它只是失败了,没有改变
a
;我猜
mapfile
必须由真实的文件系统文件(其中

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