In einem Bash-Skript möchte ich eine Zeile in Teile zerlegen und diese in einem Array speichern.
Die Zeile:
Paris, France, Europe
Ich würde sie gerne in einem Array wie diesem haben:
array[0] = Paris
array[1] = France
array[2] = Europe
Ich möchte einfachen Code verwenden, die Geschwindigkeit des Befehls spielt keine Rolle. Wie kann ich es tun?
IFS=', ' read -r -a array <<< "$string"
Beachten Sie, dass die Zeichen in $IFS
einzeln als Trennzeichen behandelt werden, so dass in diesem Fall Felder durch entweder ein Komma oder ein Leerzeichen und nicht durch die Folge der beiden Zeichen getrennt werden können. Interessanterweise werden jedoch keine leeren Felder erzeugt, wenn ein Komma oder ein Leerzeichen in der Eingabe erscheint, da das Leerzeichen speziell behandelt wird.
Um auf ein einzelnes Element zuzugreifen:
echo "${array[0]}"
Um über die Elemente zu iterieren:
for element in "${array[@]}"
do
echo "$element"
done
Um sowohl den Index als auch den Wert zu erhalten:
for index in "${!array[@]}"
do
echo "$index ${array[index]}"
done
Das letzte Beispiel ist nützlich, weil Bash-Arrays spärlich sind. Mit anderen Worten, Sie können ein Element löschen oder ein Element hinzufügen und dann sind die Indizes nicht zusammenhängend.
unset "array[1]"
array[42]=Earth
Um die Anzahl der Elemente in einem Array zu ermitteln:
echo "${#array[@]}"
Wie oben erwähnt, können Arrays spärlich sein, so dass Sie nicht die Länge verwenden sollten, um das letzte Element zu erhalten. Hier's, wie Sie es in Bash 4.2 und später können:
echo "${array[-1]}"
in jeder Version der Bash (ab 2.05b):
echo "${array[@]: -1:1}"
Größere negative Offsets wählen weiter vom Ende des Arrays entfernt. Beachten Sie das Leerzeichen vor dem Minuszeichen in der älteren Form. Es ist erforderlich.
Hier ist eine Möglichkeit, ohne IFS einzustellen:
string="1:2:3:4:5"
set -f # avoid globbing (expansion of *).
array=(${string//:/ })
for i in "${!array[@]}"
do
echo "$i=>${array[i]}"
done
Die Idee ist, die Ersetzung von Zeichenketten zu verwenden:
${string//substring/replacement}
alle Übereinstimmungen von $substring durch Leerzeichen zu ersetzen und dann die ersetzte Zeichenkette zur Initialisierung eines Arrays zu verwenden:
(element1 element2 ... elementN)
Hinweis: Diese Antwort verwendet den split+glob-Operator. Um die Expansion einiger Zeichen (wie z.B. *
) zu verhindern, ist es daher eine gute Idee, das Globbing für dieses Skript zu unterbrechen.
Manchmal ist es mir passiert, daß die in der akzeptierten Antwort beschriebene Methode nicht funktioniert hat, besonders wenn das Trennzeichen ein Wagenrücklauf ist; In diesen Fällen habe ich das Problem auf diese Weise gelöst:
string='first line
second line
third line'
oldIFS="$IFS"
IFS='
'
IFS=${IFS:0:1} # this is useful to format your code with tabs
lines=( $string )
IFS="$oldIFS"
for line in "${lines[@]}"
do
echo "--> $line"
done