
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 zsh
wäre das:
printf "%s\n" "${(ko@)hash}"
( k
um die Schlüssel zu erhalten und o
die Liste zu sortieren; @
in Anführungszeichen, um den leeren Schlüssel (falls vorhanden) beizubehalten (beachten Sie, dass bash
derzeit 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 bash
sind 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