2016-09-29 535 views
0

我在寫一個bash腳本來分析一些文件。在第一次迭代中,我爲每個分析的類別創建了包含字數的關聯數組。這些類別事先不知道,因此這些關聯數組的名稱是可變的,但都使用相同的前綴count_$category。關聯數組有一個單詞作爲關鍵字,其出現次數在該類別中作爲值計數。Bash:遍歷變量名稱

在對所有文件進行分析後,我必須總結每個類別的結果。我可以使用${count_*}迭代變量名稱,但是如何訪問這些變量名稱後面的關聯數組?對於每個關聯數組(每個count_*變量),我應該遍歷單詞和它們的計數。

我已經嘗試過像這樣的間接訪問,但它不工作:

for categorycount in ${count_*} # categorycount now holds the name of the associative array variable for each category 
do 
    array=${!categorycount} 
    for word in ${!array[@]} 
    do 
     echo "$word occurred ${array[$word]} times" 
    done 
done 
+1

你可以發佈[mcve]嗎?例如,[編輯]您的代碼來填充2個關聯數組並向我們展示您的期望。 –

+0

解決:我終於找到了一個SO問題回答這個問題 http://stackoverflow.com/a/13306800/5324593 – OKamers

+0

bash的哪個版本? 4.3有一個新的設施直接點。 –

回答

2

現代(4.3及更高版本的bash)的方式使用「namevars」,從KSH借來設施:

for _count_var in "${[email protected]}"; do 
    declare -n count=$_count_var     # make count an alias for $_count_var 
    for key in "${!count[@]}"; do     # iterate over keys, via same 
     echo "$key occurred ${count[$key]} times" # extract value, likewise 
    done 
    unset -n count        # clear that alias 
done 

declare -n count=$count_var允許"${count[foo]}"用於查找名爲count_var的關聯數組中的項目foo;同樣,count[foo]=bar將分配給相同的項目。 unset -n count然後刪除此映射。


之前打壞4.3:

for _count_var in "${[email protected]}"; do 
    printf -v cmd '_count_keys=("${!%q[@]}")' "$_count_var" && eval "$cmd" 
    for key in "${_count_keys[@]}"; do 
    var="$_count_var[$key]" 
    echo "$key occurred ${!var} times" 
    done 
done 

使用注意事項的%q,而不是直接代變量名轉換爲字符串,以產生命令,以eval。儘管在這種情況下我們可能是安全的(因爲可能的變量名稱集是受限制的),遵循這種做法減少了需要考慮的上下文的數量,以確定間接擴展是否安全。


在這兩種情況下,注意,內部變量(_count_var_count_keys等)使用不與count_*模式相匹配的名字。