
for key in ${!current_file[@]}
do
echo $key
done
我在 bash 中聲明 current_file 如下:
declare -A current_file
將 key 作為檔案插入,將 size 插入到 current_file 中。 for循環列印的輸出:
file2
file1
我想列印如下:
file1
file2
我怎樣才能這樣列印?
答案1
要列印按字母順序排序的鍵列表,並假設 GNU sort
,您可以執行以下操作:
printf '%s\0' "${!hash[@]}" | sort -z | tr '\0' '\n'
或迭代已排序的鍵列表:
while IFS= read -rd '' -u3 key; do
something with "${hash[$key]}"
done 3< <(printf '%s\0' "${!hash[@]}" | sort -z)
如果您可以保證鍵不會包含換行符,您可以將其簡化為:
printf '%s\n' "${!hash[@]}" | sort
有了zsh
,那就是:
printf "%s\n" "${(ko@)hash}"
(k
獲取鑰匙,o
訂購該列表,@
在雙引號內保留空鍵(如果有)(請注意,bash
當前有一個限制,因為它不能具有帶有空鍵的哈希元素))。
並循環它們:
for key in "${(ko@)hash}"; do
something with "$hash[$key]"
done
請注意,除了上面的最後一個之外,我們假設散列至少包含一個元素(因為printf '%s\0'
沒有參數仍然會輸出\0
就好像有一個有空鍵的元素一樣)。
無論如何,${!current_file[@]}
不加引號的編寫沒有什麼意義,因為這會在該鍵列表上呼叫 split+glob 運算子。
答案2
關聯數組在bash
就像典型語言中的雜湊/字典,並且像它們一樣它是無序的(實際上根據內部雜湊值排序)。因此,您不能期望在迭代(關聯)數組鍵時(通常)對輸出進行排序。
您需要自行排序,例如將 STDOUT 傳送到以下的 STDIN sort
:
for key in ${!current_file[@]}; do
echo $key
done | sort
或類似的東西。
如果您想要保持順序以便可以對關聯數組鍵/值執行任何基於順序的操作,則可以保留另一個索引數組作為插入的參考。以下內容應該可以讓您有一個基本的想法:
## Associative array `foo`
$ declare -A foo=([spam]=egg [baz]=cool)
## Reference indexed array `bar` containing the keys of `foo` sequentially indexed
$ bar=(spam baz)
## Retrieving in forward order
$ for i in "${bar[@]}"; do echo "$i :: ${foo[$i]}"; done
spam :: egg
baz :: cool
## Retrieving in reverse order
$ for ((i=${#bar[@]}-1; i>=0; i--)); do idx="${bar[$i]}"; echo "$idx :: ${foo[$idx]}"; done
baz :: cool
spam :: egg