从 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

相关内容