Imprime os arquivos na ordem inversa de um array associativo no bash

0
for key in ${!current_file[@]} 
    do
      echo $key      
     done

Eu declaro current_file como abaixo no bash:

declare -A current_file

insira a chave como um arquivo e tamanho como valor em current_file. Saída das impressões de loop for:

file2
file1

Eu quero imprimir como:

file1 
file2

Como posso imprimir assim?

    
por Rakib 19.12.2016 / 07:15

2 respostas

2

Para imprimir a lista de chaves ordenadas alfabeticamente e assumindo o GNU sort , você poderia fazer:

printf '%s
while IFS= read -rd '' -u3 key; do
  something with "${hash[$key]}"
done 3< <(printf '%s
printf '%s\n' "${!hash[@]}" | sort
' "${!hash[@]}" | sort -z)
' "${!hash[@]}" | sort -z | tr '
printf "%s\n" "${(ko@)hash}"
' '\n'

Ou para percorrer a lista de chaves classificadas:

for key in "${(ko@)hash}"; do
  something with "$hash[$key]"
done

Se você puder garantir que as chaves não conterão caracteres de nova linha, você poderá simplificá-lo para:

printf '%s
while IFS= read -rd '' -u3 key; do
  something with "${hash[$key]}"
done 3< <(printf '%s
printf '%s\n' "${!hash[@]}" | sort
' "${!hash[@]}" | sort -z)
' "${!hash[@]}" | sort -z | tr '
printf "%s\n" "${(ko@)hash}"
' '\n'

Com zsh , isso seria:

for key in "${(ko@)hash}"; do
  something with "$hash[$key]"
done

( k para obter as chaves, o para ordenar essa lista, @ dentro de aspas duplas para preservar a chave vazia se houver alguma (note que bash tem atualmente uma limitação em que não pode ter um elemento hash com uma chave vazia)).

E para passar por cima deles:

%pre%

Observe que, exceto para o último acima, assumimos que o hash contém pelo menos um elemento (como printf '%s${!current_file[@]}' sem argumento ainda produziria %code% como se houvesse um elemento com uma chave vazia). / p>

Em qualquer caso, escrever %code% sem aspas faz muito pouco sentido, já que invoca o operador divisão + glob nessa lista de chaves.

    
por 19.12.2016 / 16:06
1

A matriz associativa em bash é como hashes / dicionários em idiomas típicos e, como eles, não é ordenada (ordenada de acordo com o valor de hash interno, na verdade). Portanto, você não pode esperar que a saída seja (geralmente) classificada enquanto iterar sobre as chaves da matriz (associativa).

Você precisa classificá-lo, por exemplo, enviando o STDOUT para o STDIN de sort :

for key in ${!current_file[@]}; do
    echo $key      
done | sort 

ou algo semelhante.

Se você quiser manter um pedido para executar qualquer operação baseada em ordem nas chaves / valores de matriz associativa, poderá manter outro array indexado como referência de inserção. O seguinte deve dar uma ideia 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
    
por 19.12.2016 / 07:21