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