Bash bietet zwei Arten von Parametern: „skalare“ Werte und Arrays. Ein skalarer Wert kann ein String oder eine Zahl sein; er repräsentiert ein einzelnes „Ding“.
Meistens reichen skalare Werte aus, um deine Daten aufzunehmen. Aber manchmal musst du eine Liste von skalaren Werten speichern. In diesem Fall verwendest du ein Array.
Es gibt zwei Arten von Arrays:
Die ersten Abschnitte dieses Dokuments behandeln numerisch indizierte Arrays (im Folgenden einfach „Arrays“ genannt). Details zu assoziativen Arrays folgen am Ende.
Bash-Arrays können nur skalare Werte speichern. Es gibt keine Möglichkeit, ein zweidimensionales Array zu erstellen (Array von Arrays).
Du kannst ein Array initialisieren, indem du einer Variablen eine in Klammern gesetzte Liste von Elementen (möglicherweise leer) zuweist.
myarray=("one" "two" "three")
Wie bei jeder Variablenzuweisung dürfen um das Gleichheitszeichen keine Leerzeichen stehen.
Beachte, dass zwischen den Elementen keine Kommas als Trennzeichen stehen; es ist eine durch Leerraum getrennte Liste von Strings.
Tatsächlich ist die Menge an Leerraum innerhalb der Klammern völlig beliebig. Zeilenumbrüche sind erlaubt; verwende so viele du möchtest, um die Lesbarkeit zu verbessern.
myarray=(
"first element"
"second element"
"this is the last element"
)
Wenn du einer Array-Variablen auf diese Weise eine Liste von Strings zuweist, wird der erste String unter Index null gespeichert, der nächste String unter Index eins, der nächste unter Index zwei und so weiter.
Es ist möglich, ein „dünnbesetztes Array“ zu initialisieren, indem du die benötigten Indizes angibst.
raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Um es zu wiederholen: Array-Indizes beginnen bei null. Dieses Snippet gibt „true“ aus:
myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false
Du kannst den Befehl declare (oder local innerhalb einer Funktion) verwenden, um anzugeben, dass eine Variable ein Array enthält.
declare -a myarray
Es ist idiomatischer, einfach eine (vielleicht leere) in Klammern gesetzte Liste zuzuweisen, um die Variable zu initialisieren.
Wie du in der obigen Anmerkung gesehen hast, lautet die Syntax für den Zugriff auf ein Array-Element ${myarray[$index]}.
Der Index wird in eckigen Klammern angegeben.
Die geschweiften Klammern sind erforderlich.
Für numerisch indizierte Arrays ist der Index ein arithmetischer Ausdruck. Das Bash-Handbuch sagt:
Innerhalb eines arithmetischen Ausdrucks können Shell-Variablen auch über ihren Namen referenziert werden, ohne die Syntax der Parametererweiterung zu verwenden.
Das bedeutet, dass das $ für die „einfache“ Variablenerweiterung nicht erforderlich ist.
Du kannst auf Elemente wie folgt zugreifen, was etwas leichter zu lesen ist:
i=5
echo "${myarray[i]}"
# ..............^
Wenn der angegebene Index im Array nicht existiert, ist das Ergebnis der Erweiterung ein leerer String.
Um einem bestimmten Array-Eintrag einen Wert zuzuweisen, verwende diese Syntax:
myarray[10]="hello"
Um etwas an ein Array anzuhängen, verwende den verkettenden Zuweisungsoperator += und runde Klammern:
myarray+=("new element 1" "new element 2")
Typischerweise musst du über die Werte eines Arrays iterieren. Verwende eine for-Schleife (die du im Konzept Schleifen gesehen hast):
myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
echo "$value"
done
Beachte die spezielle Syntax zum Erweitern des Arrays: "${myarray[@]}"
Diese Form der Parametererweiterung ersetzt die Array-Werte als separate Wörter.
Sie entspricht in etwa:
for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"
Die Form "${myarray[@]}" funktioniert mit dünnbesetzten Arrays und erweitert sie nur zu definierten Werten.
Diese spezielle Erweiterung, bei der der Index ein At-Zeichen (@) ist, ist nur innerhalb doppelter Anführungszeichen speziell.
Hier sind noch ein paar spezielle Syntaxstücke, die wir zum Iterieren über ein Array benötigen. Sie werden im Handbuch unter Shell-Parametererweiterung beschrieben.
Um die Länge eines Arrays zu ermitteln, verwende ${#myarray[@]}, mit einem # vor dem Namen.
Die „Länge“ eines Arrays ist die Anzahl der darin enthaltenen Elemente.
Um die Liste der Indizes eines Arrays zu extrahieren, verwende "${!myarray[@]}", mit einem ! vor dem Namen und die Erweiterung in doppelten Anführungszeichen.
Bei numerisch indizierten Arrays werden die Indizes in numerischer Reihenfolge erweitert.
Manchmal brauchst du den Index ebenso wie den Wert. Es gibt ein paar Möglichkeiten, das zu tun.
Wenn du weißt, dass die Indizes eine unterbrechungsfreie Sequenz bilden, kannst du eine arithmetische for-Schleife verwenden.
for ((i = 0; i < ${#myarray[@]}; i++)); do
echo "$i -> ${myarray[i]}"
done
Beachte die Syntax ${#myarray[@]}, bei der das Zeichen # vor dem Array-Namen steht.
Da Arrays eine nullbasierte Indizierung verwenden, ist der letzte Index des Arrays um eins kleiner als die Array-Länge.
Wenn das Array dünnbesetzt ist, kannst du diese Form verwenden:
for index in "${!raindrops[@]}"; do
echo "$index -> ${raindrops[index]}"
done
Beachte die Syntax ${!myarray[@]}, bei der das Zeichen ! vor dem Array-Namen steht.
Wenn du dir den Inhalt eines Arrays ansehen möchtest, verwende den Befehl declare mit der Option -p:
a=("the 'first' element"
second
third
'the "last" element')
declare -p a
Dies gibt den Inhalt mit kanonischer Shell-Quotierung aus.
declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")
Um es zu wiederholen: Assoziative Arrays verwenden Strings als Indizes, keine Zahlen. Alles oben Geschriebene gilt auch für assoziative Arrays, allerdings mit kleinen Unterschieden. Im Allgemeinen verwenden wir den Begriff „Schlüssel“ und nicht „Index“: Assoziative Arrays ordnen Schlüssel Werten zu.
Anders als bei Arrays müssen assoziative Arrays deklariert werden.
Verwende die Option -A für declare (oder local in einer Funktion):
declare -A mymap
myfunc() {
local -A my_local_map
# ...
}
Die Schlüssel-Wert-Paare werden innerhalb der in Klammern gesetzten Liste angegeben:
mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap
Dies gibt aus:
declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Beachte, dass assoziative Arrays ungeordnet sind.
Die Deklaration und Initialisierung können in einer Zeile erfolgen.
declare -A mymap=([first]=foo [second]=bar [third]=baz)
In neueren Bash-Versionen kann die Initialisierung eine Liste (key value key value ...) verwenden.
declare -A mymap=(first foo second bar third baz)
Dieselbe Syntax wie zuvor wird verwendet, um auf Elemente zuzugreifen: ${mymap[$key]}.
Schlüssel assoziativer Arrays werden nicht in einem arithmetischen Kontext ausgewertet. Die übliche Syntax der Parametererweiterung ist erforderlich.
Die Zuweisung verwendet dieselbe Syntax wie zuvor:
mymap[$key]="$value"
Du kannst eine Schleife for value in "${mymap[@]}" verwenden, um zu iterieren.
Typischerweise möchtest du jedoch auch den Schlüssel zusammen mit dem Wert haben.
Verwende die Syntax "${!mymap[@]}", die wir oben gesehen haben.
for key in "${!mymap[@]}"; do
echo "$key -> ${mymap[$key]}"
done
Dies gibt aus
second -> bar
first -> foo
third -> baz
Um es noch einmal zu betonen: Es gibt keine Reihenfolge für die Schlüssel.