Wenn ich es tue
str="Hello World\n===========\n"
Ich bekomme das auch \n
ausgedruckt. Wie kann ich dann Newlines haben?
Wenn ich es tue
str="Hello World\n===========\n"
Ich bekomme das auch \n
ausgedruckt. Wie kann ich dann Newlines haben?
Antworten:
In können bash
Sie die Syntax verwenden
str=$'Hello World\n===========\n'
Einfache Anführungszeichen, denen ein vorangestellt $
ist, sind eine neue Syntax, mit der Escape-Sequenzen in Zeichenfolgen eingefügt werden können.
Außerdem printf
können Sie die resultierende Ausgabe in einer Variablen speichern
printf -v str 'Hello World\n===========\n'
Beide Lösungen erfordern keine Unterschale.
Wenn Sie im Folgenden die Zeichenfolge drucken müssen, sollten Sie doppelte Anführungszeichen verwenden, wie im folgenden Beispiel:
echo "$str"
Wenn Sie die Zeichenfolge ohne Anführungszeichen drucken, werden Zeilenumbrüche in Leerzeichen umgewandelt.
str=$'Hello World\n===========\n'
? Variablensubstitution?
str=$"My $PET eats:\n$PET food"
? Dieser Ansatz funktioniert für doppelte Anführungszeichen
Sie können wörtliche Zeilenumbrüche in einfache Anführungszeichen setzen (in jeder Bourne / POSIX-Shell).
str='Hello World
===========
'
Für eine mehrzeilige Zeichenfolge sind Dokumente hier häufig praktisch. Die Zeichenfolge wird als Eingabe für einen Befehl eingespeist.
mycommand <<'EOF'
Hello World
===========
EOF
Wenn Sie die Zeichenfolge in einer Variablen speichern möchten, verwenden Sie den cat
Befehl in einer Befehlsersetzung. Die Zeilenumbruchzeichen am Ende der Zeichenfolge werden durch die Befehlsersetzung entfernt. Wenn Sie die letzten Zeilenumbrüche beibehalten möchten, setzen Sie einen Stopfen an das Ende und entfernen Sie ihn anschließend. In POSIX-kompatiblen Shells können Sie schreiben, str=$(cat <<'EOF'); str=${str%a}
gefolgt von dem eigentlichen Heredoc. Für Bash muss der Heredoc jedoch vor der schließenden Klammer stehen.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
In ksh, bash und zsh können Sie $'…'
das in Anführungszeichen gesetzte Formular verwenden, um die in Anführungszeichen gesetzten Schrägstriche zu erweitern.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
arbeite nicht wie sie ist. Das )
muss in die nächste Zeile nach dem Ende des Dokuments gestellt werden EOF
. Trotzdem verliert es die nachgestellte Zeile aufgrund von Command Auswechslung.
\n
Instanzen bash
beim Erfassen eines Here-Docs in einer Variablen zu erhalten, sollten Sie IFS= read -r -d '' str <<'EOF'...
eine Alternative zum Stopper-Ansatz in Betracht ziehen (siehe meine Antwort).
Verwenden Sie "Echo"? Versuchen Sie es mit "echo -e".
echo -e "Hello World\n===========\n"
echo
es automatisch hinzugefügt wird, sofern Sie nicht -n angeben. (Die Hauptfrage ist jedoch, wie diese Zeilen in eine Variable umgewandelt werden können.)
bash
, echo -e
funktioniert unter OS X - das echo
liegt daran, dass eine Bash- Datei (und keine externe ausführbare Datei) eingebaut ist und diese eingebaute Datei unterstützt -e
. (Als eingebautes Programm sollte es auf allen Plattformen funktionieren, auf denen bash ausgeführt wird. Funktioniert übrigens auch echo -e
in ksh
und zsh
). Im Gegensatz dazu jedoch das externe echo
Dienstprogramm auf O X - /bin/echo
- in der Tat ist nicht unterstützt -e
.
Wenn Sie in Ihrem Skript häufig Zeilenumbrüche benötigen, können Sie eine globale Variable deklarieren, die einen Zeilenumbruch enthält. Auf diese Weise können Sie es in Strings mit doppelten Anführungszeichen (variable Erweiterungen) verwenden.
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
eine Unterschale benötigt werden?
"My dog eats:${NL}dog food"
Ergänzend zu den bereits vorhandenen Antworten:
Wenn Sie mit bash
und Sie lieber mit tatsächlichen Zeilenumbrüchen zur besseren Lesbarkeit , read
ist eine weitere Option für ein hier-doc in einer Variablen erfassen , die (wie auch andere Lösungen hier) nicht die Verwendung eines Sub - Shell benötigen.
# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF' # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
-r
Stellt sicher, dass read
die Eingabe nicht interpretiert wird (standardmäßig werden Backslashes speziell behandelt, dies wird jedoch selten benötigt).
-d ''
Setzt das Trennzeichen "record" auf eine leere Zeichenfolge, wodurch read
die gesamte Eingabe auf einmal gelesen wird (anstatt nur einer einzelnen Zeile).
Beachten Sie, dass durch Belassen $IFS
der Standardeinstellung (internes Feldtrennzeichen) $' \t\n'
(ein Leerzeichen, ein Tabulator, eine neue Zeile) alle führenden und nachfolgenden Leerzeichen von dem Wert, der zugewiesen wurde $str
, abgeschnitten werden , einschließlich der nachfolgenden neuen Zeile des Dokuments.
(Beachten Sie, dass , obwohl die hier-doc Körper auf der Linie beginnt nach dem Anfangsbegrenzer ( 'EOF'
hier), es ist nicht einen enthält führenden Newline).
In der Regel ist dies das gewünschte Verhalten. Wenn Sie diese nachgestellte Zeile jedoch verwenden möchten, verwenden Sie IFS= read -r -d ''
anstelle von "nur" read -r -d ''
. Beachten Sie jedoch, dass alle führenden und nachgestellten Leerzeichen dann beibehalten werden.
(Beachten Sie, dass das Voranstellen IFS=
direkt vor dem read
Befehl bedeutet, dass die Zuweisung nur während dieses Befehls wirksam ist, sodass der vorherige Wert nicht wiederhergestellt werden muss.)
Wenn Sie ein Here-Doc verwenden, können Sie auch optional Einrückungen verwenden , um die mehrzeilige Zeichenfolge aus Gründen der Lesbarkeit zu markieren:
# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
Hello World
===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]
Durch das Platzieren -
zwischen <<
und dem öffnenden Here-Doc-Trennzeichen ( 'EOF'
, hier) werden führende Tabulatorzeichen aus dem Here-Doc-Text und sogar dem schließenden Trennzeichen entfernt. Beachten Sie jedoch, dass dies nur mit tatsächlichen Tabulatorzeichen und nicht mit Leerzeichen funktioniert Editor übersetzt Tabulatortasten in Leerzeichen, zusätzliche Arbeit ist erforderlich.
du musst es so machen:
STR=$(echo -ne "Hello World\n===========\n")
Aktualisieren:
Wie Fred darauf hingewiesen hat, verlieren Sie auf diese Weise das "\ n". Gehen Sie wie folgt vor, um Variablen mit erweiterten Backslash-Sequenzen zuzuweisen:
STR=$'Hello World\n===========\n\n'
Lass es uns testen:
echo "[[$STR]]"
gibt uns jetzt:
[[Hello World
===========
]]
Beachten Sie, dass sich $ '' von $ "" unterscheidet. Die zweite Option übersetzt nach dem aktuellen Gebietsschema. Für Gottheiten siehe Abschnitt ZITIEREN in man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
Ausgabe:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
würde die nachgestellten Zeilenumbrüche, $foo
falls vorhanden, einschränken .