從 bash 中的關聯數組以相反順序列印文件

從 bash 中的關聯數組以相反順序列印文件
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

相關內容