2012-04-02 104 views
5

如何在循環中填充數組?我想這樣做:bash在循環中填充數組

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循環內添加任何內容到數組。爲什麼?

+1

你使用的是什麼版本的bash? – siride 2012-04-02 23:18:06

回答

13

你應該有什麼工作,假設你有一個支持關聯數組的開始的Bash版本。

如果我可以大膽猜測。 。 。你運行這樣的事情:

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

?那是—是你的while循環的一部分嗎?如果是這樣,那麼的問題。你看,管道中的每個命令都會收到shell的執行環境的副本。因此,while循環將填充results陣列的副本,並且當while循環完成時,該副本將消失。

編輯補充:如果這個問題,那麼作爲glenn jackman指出了一個評論,您可以通過使用process substitution,而不是修復它:

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

這樣一來,雖然command_that_outputs_keys將收到只有複製shell的執行環境(如前所述),while循環將具有原始主環境,因此可以修改原始數組。

+4

+1避免子shell的方法是使用進程替換:'while ... done <<(here here)< – 2012-04-02 23:44:35

+0

@glennjackman:輝煌,謝謝!我的第一個想法是「使用過程替換」,但我的第二個想法是「哦,等待,這將被替換爲文件名,'while'不知道將該文件作爲輸入」。 '<(...)'現在我知道了,但我永遠不會猜到這是被允許的。我已經更新了我的答案。再次感謝! :-D – ruakh 2012-04-02 23:51:54

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在這裏,慶典:GNU的bash,版本4.2.10(1)-release下(x86_64-PC-Linux的GNU)。