502 Stimmen

Wie kann ich einen Zeilenumbruch in einem String in sh haben?

Diese

STR="Hello\nWorld"
echo $STR

erzeugt als Ausgabe

Hello\nWorld

anstelle von

Hello
World

Was muss ich tun, um einen Zeilenumbruch in einer Zeichenkette zu erhalten?

Anmerkung: Diese Frage bezieht sich nicht auf echo . Ich bin mir bewusst, dass echo -e aber ich suche nach einer Lösung, die die Übergabe einer Zeichenkette (die einen Zeilenumbruch enthält) als Argument an andere Befehle, die nicht über eine ähnliche Option zur Interpretation verfügen \n 's als Zeilenumbrüche.

0 Stimmen

1voto

tlwhitec Punkte 1535

Diejenigen, die nur den Zeilenumbruch brauchen und den mehrzeiligen Code, der die Einrückung unterbricht, verachten, können das tun:

IFS="$(printf '\nx')"
IFS="${IFS%x}"

Die Bash (und wahrscheinlich auch andere Shells) verschlingen alle nachfolgenden Zeilenumbrüche nach der Befehlssubstitution, daher müssen Sie die printf Zeichenfolge mit einem Nicht-Neuzeilen-Zeichen und löschen Sie sie anschließend. Dies kann auch leicht zu einem Einzeiler werden.

IFS="$(printf '\nx')" IFS="${IFS%x}"

Ich weiß, das sind zwei Aktionen statt einer, aber mein Einrückungs- und Portabilitäts-OCD ist jetzt in Frieden :) Ursprünglich habe ich dies entwickelt, um eine nur durch Zeilenumbrüche getrennte Ausgabe aufteilen zu können, und ich habe eine Modifikation verwendet, die \r als Abschlusszeichen. Dadurch funktioniert die Zeilenumbruchsaufteilung auch bei der Dos-Ausgabe, die mit \r\n .

IFS="$(printf '\n\r')"

0voto

Adam K Dean Punkte 7236

Ich war mit keiner der Optionen hier wirklich zufrieden. Das hat bei mir funktioniert.

str=$(printf "%s" "first line")
str=$(printf "$str\n%s" "another line")
str=$(printf "$str\n%s" "and another line")

0 Stimmen

Das ist eine sehr mühsame Art zu schreiben str=$(printf '%s\n' "first line" "another line" "and another line") (die Shell wird bequemerweise (oder auch nicht) alle abschließenden Zeilenumbrüche von der Befehlssubstitution abschneiden). Mehrere Antworten hier fördern bereits printf in verschiedenen Formen, so dass ich mir nicht sicher bin, ob dies als separate Antwort einen Mehrwert darstellt.

0 Stimmen

Es ist für kurze Zeichenketten, aber wenn Sie die Dinge ordentlich halten wollen und jede Zeile tatsächlich 60 Zeichen lang ist, dann ist es ein ordentlicher Weg, es zu tun. Da dies die Lösung ist, für die ich mich letztendlich entschieden habe, bringt es etwas, wenn nicht für Sie, dann für mich selbst in der Zukunft, wenn ich zweifelsohne zurückkehre.

2 Stimmen

Auch bei langen Saiten bevorzuge ich printf '%s\n' "first line" \ (Zeilenumbruch, Einzug) 'second line' usw. Siehe auch printf -v str für die Zuweisung an eine Variable, ohne eine Subshell zu erzeugen.

-1voto

Alexey Punkte 3495

Auf meinem System (Ubuntu 17.10) funktioniert Ihr Beispiel wie gewünscht, sowohl bei der Eingabe von der Kommandozeile (in sh ) und bei Ausführung als sh Drehbuch:

[bash]§ sh
$ STR="Hello\nWorld"
$ echo $STR
Hello
World
$ exit
[bash]§ echo "STR=\"Hello\nWorld\"
> echo \$STR" > test-str.sh
[bash]§ cat test-str.sh 
STR="Hello\nWorld"
echo $STR
[bash]§ sh test-str.sh 
Hello
World

Ich denke, das beantwortet Ihre Frage: Es funktioniert einfach. (Ich habe nicht versucht, Details herauszufinden, z. B. zu welchem Zeitpunkt genau die Ersetzung des Zeilenumbruchs durch das Zeichen \n geschieht in sh ).

Ich habe jedoch festgestellt, dass sich dasselbe Skript anders verhält, wenn es ausgeführt wird mit bash und würde ausdrucken Hello\nWorld stattdessen:

[bash]§ bash test-str.sh
Hello\nWorld

Ich habe es geschafft, die gewünschte Ausgabe zu erhalten mit bash wie folgt:

[bash]§ STR="Hello
> World"
[bash]§ echo "$STR"

Beachten Sie die doppelten Anführungszeichen um $STR . Dies verhält sich identisch, wenn es gespeichert und als bash Drehbuch.

Das folgende Beispiel ergibt ebenfalls die gewünschte Ausgabe:

[bash]§ echo "Hello
> World"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X