HOWTO · Bash
String in Variablen in Bash aufteilen
Dies ist eine umfassende Beschreibung, um einen String in einem Bash-Skript in Variablen aufzuteilen.
Auf dieser Seite
Um eine durch Trennzeichen unterteilte Zeichenfolge in Bash auf benannte Variablen aufzuteilen, wählen Sie eine Methode passend zum Trennzeichen: cut wählt Felder anhand eines Trennzeichens aus, read mit IFS weist Felder direkt zu, und [[ ... =~ ... ]] erfasst Felder mit einem regulären Ausdruck. Die Beispiele zeigen, wie Sie die Ansätze anpassen und wann sie sich eignen.
Zeichenfolgen in Bash
Bash speichert Text in Zeichenfolgenvariablen. Eine Zeichenfolge kann Buchstaben, Ziffern, Satzzeichen und Leerzeichen enthalten; ein Trennzeichen ist einfach das Zeichen oder die Zeichenfolge, mit der Sie ihre Felder voneinander abgrenzen. In blue:large:cotton markieren beispielsweise die Doppelpunkte drei Felder. Bash benötigt keine gesonderte Deklaration für Zeichenfolgen. Weisen Sie den Text daher mit record="blue:large:cotton" zu, und setzen Sie Variablenerweiterungen wie "$record" in Anführungszeichen, damit der Wert als ein einziges Argument erhalten bleibt.
Zeichenfolgenfunktionen in Bash
Dieser Artikel behandelt das Aufteilen von Zeichenfolgen und nicht allgemeine Zeichenfolgenoperationen. Entscheidend ist der Unterschied zwischen der Auswahl von Feldern und dem Abgleich eines Musters: cut wählt nummerierte Felder anhand eines Trennzeichens aus, IFS gibt read an, welche Zeichen Felder voneinander trennen, und Bashs =~-Operator ermöglicht es, die zu erfassenden Teile mit einem regulären Ausdruck zu beschreiben. Wählen Sie die Methode danach aus, ob die Eingabe ein einfaches Trennzeichen, mehrere Trennzeichen oder eine Struktur enthält, die ein Muster erfordert.
Zeichenfolge in Bash in Variablen aufteilen
Bei einem einfachen Trennzeichen können Sie die getrennten Felder benannten Variablen zuweisen. Dieses eigenständige Beispiel verwendet cut, um drei durch Bindestriche getrennte Felder auszuwählen, und weist sie anschließend mit read zu. Die sichtbaren Ausgabebezeichnungen wie „First“ und „Second“ bleiben im Beispiel auf Englisch:
record="0123-456-789"
fields=$(printf '%s\n' "$record" | cut -d '-' -f 1-3)
IFS='-' read -r first second third <<< "$fields"
printf 'First: %s\nSecond: %s\nThird: %s\n' "$first" "$second" "$third"
Mit dem Befehl cut eine Zeichenfolge in Bash in Variablen aufteilen
Die Option -d des Befehls cut legt ein einzelnes Trennzeichen fest, und -f wählt eine oder mehrere Feldnummern aus. Im obigen Beispiel fordert -f 1-3 die ersten drei Felder an. Wenn Sie das Ergebnis abfangen und an read übergeben, werden die Felder Shell-Variablen zugewiesen. Setzen Sie die Eingabeerweiterung in Anführungszeichen und verwenden Sie printf, um den Datensatz als eine verlässliche Zeile zu übergeben.
Verwenden Sie cut, wenn Datensätze ein einheitliches einzelnes Trennzeichen haben und Sie bestimmte Felder benötigen. Der Befehl behandelt mehrere unterschiedliche Trennzeichen nicht als gleichwertig und verändert den ursprünglichen Datensatz nicht. Fehlt das Trennzeichen, gibt cut die Zeile unverändert weiter. Die Feldauswahl prüft daher nicht, ob ein Datensatz die erwartete Form hat.
Mit einem internen Feldtrenner (IFS) eine Zeichenfolge in Bash in Variablen aufteilen
read teilt seine Eingabe anhand von IFS, dem internen Feldtrenner (Internal Field Separator), auf. Setzen Sie IFS nur für diesen einen Befehl, damit das spätere Aufteilungsverhalten der Shell unverändert bleibt. Dieses Beispiel verwendet Bindestriche und Kommas als Trennzeichen:
record="red-blue,green"
IFS='-,' read -r first second third <<< "$record"
printf 'First: %s\nSecond: %s\nThird: %s\n' "$first" "$second" "$third"
Die Option -r behandelt Backslashes wörtlich, während "$record" in Anführungszeichen die Eingabe schützt. Jedes Zeichen in IFS ist ein Trennzeichen; die Zeichen müssen nicht gemeinsam als mehrteilige Zeichenfolge vorkommen. Da die Trennzeichen hier keine Leerraumzeichen sind, können aufeinanderfolgende Trennzeichen ein leeres Feld darstellen. Wenn Sie weniger Variablennamen als Felder angeben, erhält die letzte Variable die verbleibende Eingabe einschließlich der Trennzeichen zwischen den restlichen Feldern. Standardmäßig enthält IFS Leerzeichen, Tabulatoren und Zeilenumbrüche. read behandelt sie als Leerraumtrennzeichen und entfernt sie an den Rändern.
Mit read und sed eine Zeichenfolge in Bash in Variablen aufteilen
Verwenden Sie sed, um jedes passende Zeichen in ein Zeichen mit nachfolgendem Markierungszeichen umzuwandeln. Anschließend kann read anhand dieser Markierung aufteilen. Anders als beim Aufteilen mit den standardmäßigen Leerraumtrennzeichen bleiben dabei Leerzeichen aus der ursprünglichen Zeichenfolge erhalten:
record="A B!"
transformed=$(printf '%s' "$record" | sed 's/./&|/g')
IFS='|' read -r -a characters <<< "$transformed"
printf 'First: %s\nSecond: %s\nThird: %s\nFourth: %s\n' "${characters[0]}" "${characters[1]}" "${characters[2]}" "${characters[3]}"
Hier fügt sed nach jedem Treffer | ein, und read -a speichert die daraus entstehenden Felder in einem indizierten Array. Die Markierung dient nur als Trennzeichen für diese Umwandlung; sie ist keine allgemeine Methode zum Parsen strukturierter Datensätze. Die Bedeutung von . in sed kann von der aktiven Locale abhängen. Diese Technik eignet sich deshalb am besten für einfachen Text, bei dem dieses Verhalten akzeptabel ist. Ein als Trennzeichen eingefügtes Leerzeichen würde bei der standardmäßigen Verarbeitung von Leerraum durch IFS entfernt. Daher verwendet das Beispiel | und setzt IFS ausdrücklich.
Mit einem regulären Ausdruck und einem Match eine Zeichenfolge in Bash in Variablen aufteilen
Bashs Bedingung [[ string =~ regex ]] prüft, ob eine Zeichenfolge einem regulären Ausdruck entspricht. Erfasste Klammergruppen sind in BASH_REMATCH verfügbar: Element null enthält den vollständigen Treffer, die Elemente ab eins enthalten die erfassten Gruppen. Speichern Sie den regulären Ausdruck in einer nicht in Anführungszeichen gesetzten Variablen rechts von =~, damit Bash ihn als Muster behandelt:
record="31-28-31"
pattern='^([^-]+)-([^-]+)-([^-]+)$'
if [[ $record =~ $pattern ]]; then
first=${BASH_REMATCH[1]}
second=${BASH_REMATCH[2]}
third=${BASH_REMATCH[3]}
printf 'First: %s\nSecond: %s\nThird: %s\n' "$first" "$second" "$third"
fi
record="high,risk"
pattern='^([^,]+),([^,]+)$'
if [[ $record =~ $pattern ]]; then
first=${BASH_REMATCH[1]}
second=${BASH_REMATCH[2]}
printf 'First: %s\nSecond: %s\n' "$first" "$second"
fi
Das erste Muster erfasst genau drei Felder, die keine Bindestriche enthalten; das zweite erfasst zwei durch Kommas getrennte Werte. Passen Sie die Gruppen an, wenn sich die erwartete Anzahl oder Form der Felder ändert. Ein Treffer ist nicht garantiert. Verwenden Sie Zuweisungen mit BASH_REMATCH daher nur innerhalb des erfolgreichen Zweigs. Diese Methode eignet sich, wenn eine Trennzeichenregel überprüft oder mehrere Teile auf einmal erfasst werden müssen. Bei einem einfachen festen Trennzeichen ist IFS oder cut kürzer.