Ar

Arrays in Bash

{one: "1 Übung", other: "%{count} Übungen"}

Über Arrays

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:

  • Numerisch indizierte Arrays ordnen einen Ganzzahl-Schlüssel einem String-Wert zu. (Andere Sprachen nennen das vielleicht eine „Liste“ oder eine „Sequenz“.)
  • Assoziative Arrays ordnen einen String-Schlüssel einem String-Wert zu. (Andere Sprachen nennen das vielleicht eine „Map“ oder ein „Wörterbuch“.)

Die ersten Abschnitte dieses Dokuments behandeln numerisch indizierte Arrays (im Folgenden einfach „Arrays“ genannt). Details zu assoziativen Arrays folgen am Ende.

Caution

Bash-Arrays können nur skalare Werte speichern. Es gibt keine Möglichkeit, ein zweidimensionales Array zu erstellen (Array von Arrays).

Deklarieren und Initialisieren einer Array-Variable

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")
Note

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.

Zugriff auf Elemente eines Arrays

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.

Note

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.

Zuweisen zu einem Array

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")

Über ein Array iterieren

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.

Weitere spezielle Parametererweiterungen

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.

Über Array-Indizes iterieren

Manchmal brauchst du den Index ebenso wie den Wert. Es gibt ein paar Möglichkeiten, das zu tun.

  1. 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.

  2. 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.

Ein Array untersuchen

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")

Assoziative Arrays

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.

Ein assoziatives Array deklarieren

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

Ein assoziatives Array initialisieren

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")
Note

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)

Auf Werte zugreifen

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.

Einem assoziativen Array zuweisen

Die Zuweisung verwendet dieselbe Syntax wie zuvor:

mymap[$key]="$value"

Iterieren

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.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab