在循环中填充Bash数组

8
如何在循环中填充数组?我想做这样的事情:
declare -A results

results["a"]=1
results["b"]=2

while read data; do
results[$data]=1
done

for i in "${!results[@]}"
do
  echo "key  : $i"
  echo "value: ${results[$i]}"
done

但是在for循环中似乎无法向数组中添加任何内容。为什么?


2
你正在使用哪个版本的Bash? - siride
2个回答

25

假设你一开始就使用支持关联数组的Bash版本,那么你所拥有的应该是可以运行的。

如果我可以猜一个大概……你是否在运行类似于这样的东西:

command_that_outputs_keys \
  | while read data; do
        results[$data]=1
    done

? 那么 - 你的while循环是否是管道的一部分?如果是,那就是问题所在。因为管道中的每个命令都会接收shell执行环境的一个副本。所以while循环将会填充一个results数组的副本,当while循环完成后,该副本就消失了。

编辑补充: 如果确实是这个问题,正如glenn jackman在评论中指出的那样,您可以使用进程替代来解决:

while read data; do
    results[$data]=1
done < <(command_that_outputs_keys)

这样,虽然command_that_outputs_keys只会收到 shell 执行环境的副本(与之前一样),但while循环将具有原始的主环境,因此它将能够修改原始数组。


8
避免使用子Shell的方法是使用进程置换:while ... done < <(command here) - glenn jackman

1

看起来运行良好:

$ cat mkt.sh 
declare -A results

results["a"]=1
results["b"]=2

while read data; do
  results[$data]=1
done << EOF
3
4
5
EOF

for i in "${!results[@]}"
do
  echo "key  : $i"
  echo "value: ${results[$i]}"
done

$ ./mkt.sh 
key  : a
value: 1
key  : b
value: 2
key  : 3
value: 1
key  : 4
value: 1
key  : 5
value: 1
$ 

这里是Ubuntu 11.10,bash版本为GNU bash,版本号为4.2.10(1)-release (x86_64-pc-linux-gnu)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接