
for key in ${!current_file[@]}
do
echo $key
done
Declaro current_file como a continuación en bash:
declare -A current_file
inserte la clave como archivo y el tamaño como valor en archivo_actual. Salida de las impresiones del bucle for:
file2
file1
Quiero imprimir como:
file1
file2
¿Cómo puedo imprimir así?
Respuesta1
Para imprimir la lista de claves ordenadas alfabéticamente, y asumiendo GNU sort
, podrías hacer:
printf '%s\0' "${!hash[@]}" | sort -z | tr '\0' '\n'
O para iterar sobre la lista ordenada de claves:
while IFS= read -rd '' -u3 key; do
something with "${hash[$key]}"
done 3< <(printf '%s\0' "${!hash[@]}" | sort -z)
Si puede garantizar que las claves no contendrán caracteres de nueva línea, puede simplificarlo a:
printf '%s\n' "${!hash[@]}" | sort
Con zsh
, eso sería:
printf "%s\n" "${(ko@)hash}"
( k
para obtener las claves, o
para ordenar esa lista, @
entre comillas dobles para conservar la clave vacía, si corresponde (tenga en cuenta que bash
actualmente tiene la limitación de que no puede tener un elemento hash con una clave vacía)).
Y para recorrerlos:
for key in "${(ko@)hash}"; do
something with "$hash[$key]"
done
Tenga en cuenta que, a excepción del último anterior, asumimos que el hash contiene al menos un elemento (ya que printf '%s\0'
sin ningún argumento el resultado sería \0
como si hubiera un elemento con una clave vacía).
En cualquier caso, escribir ${!current_file[@]}
sin comillas tiene muy poco sentido ya que invoca el operador split+glob en esa lista de claves.
Respuesta2
La matriz asociativa bash
es como hashes/diccionarios en los lenguajes típicos y, como ellos, está desordenada (en realidad, está ordenada según el valor hash interno). Por lo tanto, no puede esperar que la salida se ordene (generalmente) mientras se itera sobre las claves de la matriz (asociativa).
Debe ordenarlo usted mismo, por ejemplo enviando el STDOUT al STDIN de sort
:
for key in ${!current_file[@]}; do
echo $key
done | sort
o algo similar.
Si desea mantener un orden para poder realizar cualquier operación basada en el orden en las claves/valores de la matriz asociativa, puede mantener otra matriz indexada como referencia de inserción. Lo siguiente debería darle una idea básica:
## 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