Durchlaufen einer mehrzeiligen Zeichenfolge, die in einer Variablen gespeichert ist


17

Ich habe gelesen, dass es schlecht ist, Dinge zu schreiben, wie es for line in $(command)der richtige Weg zu sein scheint:

command | while IFS= read -r line; do echo $line; done

Das funktioniert super. Was aber, wenn ich den Inhalt einer Variablen und nicht das direkte Ergebnis eines Befehls durchlaufen möchte ?

Stellen Sie sich beispielsweise vor, Sie erstellen die folgende Datei quickfox:

The quick brown
foxjumps\ over -
the
lazy ,
dog.

Ich möchte in der Lage sein, so etwas zu tun:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect

Antworten:


18

In modernen Shells wie bash und zsh gibt es einen sehr nützlichen Redirector "<<<", der einen String als Eingabe akzeptiert. Also würdest du tun

while IFS= read -r line ; do echo $line; done <<< "$variable"

Ansonsten können Sie immer tun

echo "$variable" | while IFS= read -r line ; do echo $line; done

Entschuldigung, ich hätte natürlich darüber nachdenken sollen, den Inhalt wiederzugeben. Aber trotzdem danke für die schnelle Antwort!
Sheljohn

1
$variableWenn Sie es verwenden, müssen Sie es in doppelte Anführungszeichen setzen, andernfalls whileerhält die Schleife nur eine Eingabezeile. Siehe zum Beispiel den Unterschied in der Leistung zwischen echo $variablevs echo "$variable"oder cat <<< $variablevs cat <<< "$variable".
cas

@cas Tatsächlich hängt es davon ab, was in $ variable enthalten ist. In dem vom OP präsentierten Fall ("variable = $ (cat quickfox)") funktioniert es ohne die zusätzlichen Anführungszeichen. Aber für den allgemeinen Fall haben Sie recht. Ich bearbeite meine Antwort. Vielen Dank.
Lgeorget

Die variable=$(cat quickfox)Frage im OP selbst liefert ein Beispiel für das, worüber ich gesprochen habe. Wenn Sie das $variablein Anführungszeichen setzen, werden die Zeilenumbrüche eingeschlossen, wenn Sie es ohne Anführungszeichen verwenden, werden die Zeilenumbrüche von der Shell in Leerzeichen übersetzt. Wenn Sie zeilenweise lesen und verarbeiten, ist dies ein großer Unterschied - bei ersteren gibt es mehrere Eingabezeilen, bei letzteren nur eine Eingabezeile. Die Eingabedaten sind oberflächlich ähnlich, aber in der Praxis in diesen beiden Fällen völlig unterschiedlich.
cas

Beispiel: Gibt mit diesen Eingabedaten cat <<< "$variable" | wc -l5 cat <<< $variable | wc -lzurück. Gibt 1 zurück. Wenn Sie Leerzeichen (einschließlich Zeilenumbrüche, Tabulatoren, einzelne oder mehrere Leerzeichen) in einer Variablen beibehalten möchten / müssen, MÜSSEN Sie die Variable bei der Verwendung in doppelte Anführungszeichen setzen, andernfalls Sie werden alle in ein einzelnes Leerzeichen zwischen jedem "Wort" umgewandelt.
cas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.