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

525voto

amphetamachine Punkte 24877

Wenn Sie die Bash verwenden, ist die Lösung, dass Sie $'string' zum Beispiel:

$ STR=$'Hello\nWorld'
$ echo "$STR" # quotes are required here!
Hello
World

Wenn Sie so ziemlich jede andere Shell verwenden, fügen Sie den Zeilenumbruch einfach unverändert in die Zeichenkette ein:

$ STR='Hello
> World'

Bash ist ziemlich nett. Sie akzeptiert mehr als nur \n im $'' Zeichenfolge. Hier ist ein Auszug aus der Bash-Handbuchseite:

Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:
      \a     alert (bell)
      \b     backspace
      \e
      \E     an escape character
      \f     form feed
      \n     new line
      \r     carriage return
      \t     horizontal tab
      \v     vertical tab
      \\     backslash
      \'     single quote
      \"     double quote
      \nnn   the eight-bit character whose value is the octal value
             nnn (one to three digits)
      \xHH   the eight-bit character whose value is the hexadecimal
             value HH (one or two hex digits)
      \cx    a control-x character

The expanded result is single-quoted, as if the dollar sign had not
been present.

A double-quoted string preceded by a dollar sign ($"string") will cause
the string to be translated according to the current locale. If the
current locale is C or POSIX, the dollar sign is ignored. If the
string is translated and replaced, the replacement is double-quoted.

86 Stimmen

Das gilt für die Bash, aber nicht für POSIX sh.

9 Stimmen

+1-nur eine Anmerkung: export varDynamic="$varAnother1$varAnother2"$' \n '

0 Stimmen

Unter POSIX würde ich eingeben IFS='^J' und verwenden Sie diese. Ist eine andere Möglichkeit bekannt?

216voto

Jens Punkte 65511

Echo ist so neumodisch und voller Gefahren, dass seine Verwendung zu Kerndumps von nicht weniger als 4 GB führen sollte. Im Ernst, die Probleme von Echo waren der Grund, warum der Unix-Standardisierungsprozess schließlich das printf Dienstprogramm, das alle Probleme ausräumt.

Um einen Zeilenumbruch in einer Zeichenkette zu erhalten, gibt es also zwei Möglichkeiten:

# 1) Literal newline in an assignment.
FOO="hello
world"
# 2) Command substitution.
BAR=$(printf "hello\nworld\n") # Alternative; note: final newline is deleted
printf '<%s>\n' "$FOO"
printf '<%s>\n' "$BAR"

So! Kein SYSV vs. BSD Echo-Wahnsinn, alles wird sauber gedruckt und vollständig portable Unterstützung für C Escape-Sequenzen. Bitte benutzen Sie alle printf jetzt für Ihren gesamten Output-Bedarf und blicken Sie nie wieder zurück.

4 Stimmen

Vielen Dank für diese Antwort, ich denke, sie gibt wirklich gute Ratschläge. Beachten Sie jedoch, dass meine ursprüngliche Frage nicht wirklich darauf abzielte, wie man echo dazu bringt, Zeilenumbrüche zu drucken, sondern wie man einen Zeilenumbruch in eine Shell-Variable bekommt. Sie zeigen auch, wie man das mit printf macht, aber ich denke, dass die Lösung aus amphetamachine 使って $'string' ist noch sauberer.

15 Stimmen

Nur für eine mangelhafte Definition von "sauber". Die $'foo' Syntax ist seit 2013 keine gültige POSIX-Syntax mehr. Viele Shells werden sich beschweren.

1 Stimmen

Vielen Dank für diese Antwort. Ich bekomme so geschraubt versuchen, Bash-spezifische Sachen in sh-Dateien allzu oft zu verwenden.

80voto

zvezda Punkte 1153

Auf der Grundlage der anderen Antworten habe ich Folgendes getan

NEWLINE=$'\n'
my_var="__between eggs and bacon__"
echo "spam${NEWLINE}eggs${my_var}bacon${NEWLINE}knight"

# which outputs:
spam
eggs__between eggs and bacon__bacon
knight

51voto

Simon Ndunda Punkte 804

Ich finde die -e Flagge elegant und geradlinig

bash$ STR="Hello\nWorld"

bash$ echo -e $STR
Hello
World

Wenn die Zeichenfolge die Ausgabe eines anderen Befehls ist, verwende ich einfach Anführungszeichen

indexes_diff=$(git diff index.yaml)
echo "$indexes_diff"

2 Stimmen

Dies wurde bereits in anderen Antworten erwähnt. Außerdem habe ich die Frage bearbeitet, um zu betonen, dass es sich um eine Frage handelt, die bereits gestellt wurde. no über echo .

1 Stimmen

Dies ist keine Antwort auf die Frage

0 Stimmen

Das beantwortet genau die Frage, nach der ich gesucht habe! Danke!

35voto

Pace Punkte 38003

Das Problem liegt nicht an der Hülle. Das Problem liegt vielmehr bei der echo Befehl selbst und das Fehlen von Anführungszeichen um die Variableninterpolation. Sie können versuchen, mit echo -e aber das wird nicht auf allen Plattformen unterstützt, und einer der Gründe dafür ist, dass printf wird jetzt aus Gründen der Portabilität empfohlen.

Sie können auch versuchen, den Zeilenumbruch direkt in Ihr Shell-Skript einzufügen (falls Sie ein Skript schreiben), so dass es aussieht wie...

#!/bin/sh
echo "Hello
World"
#EOF

oder gleichwertig

#!/bin/sh
string="Hello
World"
echo "$string"  # note double quotes!

0 Stimmen

Da dies mehr oder weniger die kanonische Frage für die nicht Bash-Frage (und das ist chronologisch die erste Antwort) und vor allem, dass die Suchmaschinen es mögen, vielleicht hinzufügen. ein Beispiel für printf? (Aber sans "Bearbeiten:", "Aktualisieren:" oder ähnlich - die Antwort sollte so aussehen, als wäre sie heute geschrieben worden).

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