Drucken Sie Dateien in umgekehrter Reihenfolge aus einem assoziativen Array in Bash

Drucken Sie Dateien in umgekehrter Reihenfolge aus einem assoziativen Array in Bash
for key in ${!current_file[@]} 
    do
      echo $key      
     done

Ich deklariere current_file wie unten in bash:

declare -A current_file

Schlüssel als Datei und Größe als Wert in aktuelle_Datei einfügen. Die Ausgabe der For-Schleife lautet:

file2
file1

Ich möchte wie folgt drucken:

file1 
file2

Wie kann ich so drucken?

Antwort1

Um die Liste der Schlüssel alphabetisch sortiert auszudrucken (GNU vorausgesetzt) sort, können Sie Folgendes tun:

printf '%s\0' "${!hash[@]}" | sort -z | tr '\0' '\n'

Oder um über die sortierte Liste der Schlüssel zu iterieren:

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

Wenn Sie garantieren können, dass die Schlüssel keine Zeilenumbruchzeichen enthalten, können Sie es wie folgt vereinfachen:

printf '%s\n' "${!hash[@]}" | sort

Mit zshwäre das:

printf "%s\n" "${(ko@)hash}"

( kum die Schlüssel zu erhalten und odie Liste zu sortieren; @in Anführungszeichen, um den leeren Schlüssel (falls vorhanden) beizubehalten (beachten Sie, dass bashderzeit die Einschränkung besteht, dass kein Hash-Element mit leerem Schlüssel vorhanden sein kann)).

Und um sie zu durchlaufen:

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

Beachten Sie, dass wir mit Ausnahme des letzten oben davon ausgehen, dass der Hash mindestens ein Element enthält (da printf '%s\0'ohne Argument immer noch so ausgegeben würde \0, als ob es ein Element mit einem leeren Schlüssel gäbe).

In jedem Fall ${!current_file[@]}ergibt das Schreiben ohne Anführungszeichen wenig Sinn, da dadurch der Operator „Split+Glob“ auf dieser Schlüsselliste aufgerufen wird.

Antwort2

Assoziative Arrays bashsind wie Hashes/Wörterbücher in typischen Sprachen und wie diese sind sie ungeordnet (tatsächlich nach dem internen Hashwert geordnet). Sie können also nicht erwarten, dass die Ausgabe (im Allgemeinen) sortiert ist, während Sie über die (assoziativen) Array-Schlüssel iterieren.

Sie müssen es selbst sortieren, indem Sie beispielsweise STDOUT an STDIN von senden sort:

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

oder etwas ähnliches.


Wenn Sie eine Reihenfolge beibehalten möchten, sodass Sie alle reihenfolgebasierten Operationen an den Schlüsseln/Werten des assoziativen Arrays durchführen können, können Sie ein anderes indiziertes Array als Einfügereferenz beibehalten. Das Folgende sollte Ihnen eine grundlegende Vorstellung geben:

## 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

verwandte Informationen