如何使用命令输出填充bash关联数组?

时间:2016-09-09 18:34:31

标签: bash

我尝试使用命令的输出填充关联数组。我可以在没有命令的情况下做到:

$ declare -A x=( [first]=foo [second]=bar )
$ echo "${x[first]}, ${x[second]}"
foo, bar

我可以使用命令输出填充非关联数组:

$ declare y=( $(echo 'foo bar') )
$ echo "${y[0]}, ${y[1]}"
foo, bar

但是当我尝试构建上述两个来创建一个将从命令填充关联数组的语句时,我收到以下错误消息:

$ declare -A z=( $(echo '[first]=foo [second]=bar') )
-bash: z: $(echo '[first]=foo [second]=bar'): must use subscript when assigning associative array

为什么我收到该错误消息以及使用命令输出填充关联数组的正确语法是什么?我试图避免对the usual reasons使用eval,不想使用临时文件,当然echo仅用作产生效果的命令的示例问题,真正的命令会更复杂。

所以,基于以下几个答案,看起来只是我引用的问题:

$ declare -A z="( $(echo '[first]=foo [second]=bar') )"
$ echo "${z[first]}, ${z[second]}"
foo, bar

并且索引和值中包含空格:

$ declare -A z="( $(echo '[first field]="foo with space" [second]="space bar"') )"
$ echo "${z[first field]}, ${z[second]}"
foo with space, space bar

3 个答案:

答案 0 :(得分:3)

这是一种传统的while循环方法,用于从命令的输出中填充关联数组:

while IFS= read -r; do
   declare -A z+="( $REPLY )"
done < <(printf '[first]=foo [second]=bar\n[third]=baz\n')

# check output
$> echo "${z[first]}, ${z[second]}, ${z[third]}"
foo, bar, baz

# or declare -p
$> declare -p z
declare -A z='([third]="baz" [second]="bar" [first]="foo" )'

编辑:您的原始尝试也适用于正确的引号:

$> unset z

$> declare -A z="( $(echo '[first]=foo [second]=bar') )"

$> declare -p z
declare -A z='([second]="bar" [first]="foo" )'

答案 1 :(得分:2)

我认为这有些脆弱,但您可以将整个z=(...)赋值作为命令替换的结果。

declare -A "$(echo z="($(echo '[first]=foo [second]=bar'))")"

答案 2 :(得分:1)

鉴于这是有效的:

declare -A z=([first]=$(echo 'foo') [second]=$(echo 'bar'))

我猜测Bash在进行任何替换之前需要查看关联数组初始化列表。所以我没有办法避免eval

eval "declare -A z=($(echo '[first]=foo [second]=bar'))"

避免eval的“通常原因”是什么?