
for key in ${!current_file[@]}
do
echo $key
done
bashでcurrent_fileを次のように宣言します。
declare -A current_file
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
上記の最後の項目を除いて、ハッシュに少なくとも1つの要素が含まれているとします(引数がnullキーを持つ要素があるかのように出力されprintf '%s\0'
ないため)。\0
とにかく引用符なしで書くことはほとんど意味がありません${!current_file[@]}
。なぜなら、そのキーリストから分割+グローブ演算子を呼び出すからです。
答え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