Die Bash-Manpage beschreibt die Verwendung von ${!a}
, um den Inhalt der Variablen zurückzugeben, deren Name der Inhalt von ist a
(eine Indirektionsebene).
Ich möchte wissen, wie alle Elemente in einem Array mit diesem zurückgegeben werden können, d. H.
a=(one two three)
echo ${a[*]}
kehrt zurück
one two three
Ich möchte für:
b=a
echo ${!b[*]}
das gleiche zurückzugeben. Leider nicht, sondern kehrt 0
stattdessen zurück.
Aktualisieren
Angesichts der Antworten stelle ich jetzt fest, dass mein Beispiel zu einfach war, da natürlich so etwas wie:
b=("${a[@]}")
Wird genau das erreichen, was ich gesagt habe.
Also, hier ist was ich versucht habe zu tun:
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST=LIST_$whichone
LIST=${!_LIST[*]}
Das sorgfältige Lesen der Bash-Manpage zeigt natürlich, dass dies nicht wie erwartet funktioniert, da die letzte Zeile einfach die Indizes des "Arrays" zurückgibt $_LIST
(überhaupt kein Array).
In jedem Fall sollte Folgendes die Arbeit erledigen (wie bereits erwähnt):
LIST=($(eval echo \${$_LIST[*]}))
oder ... (der Weg, den ich schließlich gegangen bin):
LIST_lys="lys1 lys2"
...
LIST=(${!_LIST})
Vorausgesetzt natürlich, dass Elemente keine Leerzeichen enthalten.
[@]
dem Zeiger hinzu_LIST="LIST_${whichone}[@]"
undLIST=("${!_LIST}")
kopieren Sie das Array mit. Es ist eine gute Idee, Variablennamen in Kleinbuchstaben zu verwenden, um Konflikte mit Umgebungsvariablen (Großbuchstaben) zu vermeiden.Antworten:
Ich denke, die Verwendung der indirekten Referenz der Bash-Variablen sollte wörtlich behandelt werden.
Z.B. Für Ihr ursprüngliches Beispiel:
Für das letzte reale Szenario glaube ich, dass der folgende Code die Arbeit erledigen würde.
Es ist besser, die Notation zu verwenden
"${var[@]}"
, um die$IFS
Parametererweiterung nicht zu verfälschen. Hier ist der endgültige Code.quelle
Sie müssen die Elemente explizit kopieren. Für ein indiziertes Array:
Für ein assoziatives Array (beachten Sie, dass dies
a
der Name der Arrayvariablen ist, nicht eine Variable, deren Wert der Name einer Arrayvariablen ist):Wenn Sie den Variablennamen in einem Array haben, können Sie die Element-für-Element-Methode mit einem zusätzlichen Schritt verwenden, um die Schlüssel abzurufen.
(Achtung, der Code in diesem Beitrag wurde direkt in einen Browser eingegeben und nicht getestet.)
quelle
\${!$name[@]}
in der ersten Zeile befinden, damit die erste Erweiterung nur den Namen '$ name' hat und die${!a[@]}
für die Auswertung gespeichert wird, und dasselbe in der for-Schleife mit\${$name}
. Die beiden anderen Backslashes vor '$ k' sind dort ebenfalls nicht unbedingt erforderlich.${!b[*]}
wird auf die im Array verwendeten Indizes erweitertb
.Was Sie möchten, muss in zwei Schritten erledigt werden, um zu
eval
helfen :eval echo \${$b[*]}
. (Beachten Sie das,\
was sicherstellt, dass der erste$
den ersten Schritt, die variable Erweiterung, besteht und erst im zweiten Schritt um erweitert wirdeval
.)Laut Parameter wird Expansion
!
sowohl für die indirekte Erweiterung ({!a}
) als auch für Namen verwendet, die dem Präfix (${!a*}
) und der Liste der Array-Schlüssel (${!a[*]}
) entsprechen. Da die Liste der Array-Schlüssel dieselbe Syntax hat wie Ihre beabsichtigte indirekte Erweiterung + Array-Element-Erweiterung, wird die letztere nicht so unterstützt, wie sie ist.quelle
${!a}
wird auf den Wert der Variablen erweitert, deren Name lautet$a
. Dies wird im Handbuch im Abschnitt, der mit „Wenn das erste Zeichen des Parameters ein Ausrufezeichen (!
) ist, wird eine Ebene der variablen Indirektion eingeführt“ ziemlich knapp beschrieben .${!
mehrdeutig ist, da das Verhalten anders ist, wenn es sich um ein Array handelt, mit dem Sie es zu tun haben.Um indirekt auf Arrays zuzugreifen, fügen Sie einfach
[@]
die indirekte Variable hinzub=a[@]
.Wenn diese Variablen gesetzt sind:
Dann wird dies funktionieren:
Oder einfach:
Ein solches Array könnte wie folgt kopiert werden:
Und dann gedruckt mit:
In einem Skript:
Natürlich kopieren alle oben genannten Elemente ein nicht spärliches Array. Eine, in der alle Indizes einen Wert haben.
spärliche Arrays
Ein Array mit geringer Dichte kann nicht definierte Elemente enthalten.
Definiert zum Beispiel
a[8]=1234
ein Element und in Bash existieren 0 bis 7 nicht.Verwenden Sie diese Methode, um ein solches spärliches Array zu kopieren
Drucken Sie das alte Array:
Ersetzen Sie den Namen des Arrays und erfassen Sie die Zeichenfolge:
Bei der Bewertung der so erstellten Zeichenfolge wurde das neue Array definiert:
quelle