Gibt es eine Möglichkeit, einen Blackslash mit einem Zeilenvorschub in bash zu wiederholen?

619
InFlames

Ich versuche eine Zeile mit zu beenden \und habe etwas anderes in einer neuen Zeile. Zuerst habe ich das gemacht, aber es druckt nur das \ n:

$ echo -e "Test\\\nNewline"  Test\nNewline 

Ich habe diesen Weg ausprobiert, aber es wird nach dem Backslash ein Leerzeichen eingefügt:

$ echo -e "Test\\ \nNewline" Test\  Newline 

Wie kann ich das machen, so dass nach dem Platz kein Platz ist \?

UPDATE: Es gibt jetzt kein Problem, da ich sehe, dass das Hinzufügen von zwei weiteren Schrägstrichen das gewünschte Ergebnis ergibt. Aber ich frage mich immer noch, warum das so ist.

$ echo -e "Test\\\\\nNewline" Test\ Newline 
3
Ich weiß es nicht, aber etwas komisches über Anführungszeichen. Versuchen Sie dieses `$ echo -e 'tt \\\ nP'` barlop vor 8 Jahren 0
Nehmen Sie also Ihr erstes Beispiel, das Ihrer Meinung nach funktionieren sollte und nicht. Versuchen Sie, doppelte Anführungszeichen in einfache Anführungszeichen zu setzen barlop vor 8 Jahren 0

2 Antworten auf die Frage

2
Steven

Bash-Referenzhandbuch: Doppelte Anführungszeichen: Bei doppelten Anführungszeichen werden umgekehrte Schrägstriche entfernt, auf die eines dieser Zeichen (einschließlich des umgekehrten Schrägstrichs) folgt.

Daher "Test\\\\\nNewline"wird mit ersetzt, Test\\nNewlinebevor es als Parameter an den echoBefehl übergeben wird.

Um dies zu demonstrieren:

$ echo -e "Test\\\\\nNewline" Test\ Newline  $ echo -e 'Test\\\nNewline' Test\ Newline 
Zweifellos liegt die Antwort innerhalb dieser Regeln, aber könnten Sie erklären, wie dies dazu führt, dass "\\\\\" n benötigt wird, um eine neue Zeile rückwärts zu formen? So wird zum Beispiel für diese 5 Backslashes n (was in seinem Beispiel ist) zu dem, was es wird. barlop vor 8 Jahren 0
Danke, das erklärt es! In dem einfachen Anführungszeichen fehlt ein \. ;) InFlames vor 8 Jahren 0
@InFlames behoben. Steven vor 8 Jahren 0
Echo ohne -e ist eine Sache. Aber er hat -Ee in seinem Beispiel wiederholt, sodass Ihre Demonstration ein Ergebnis mit mehr Backslashes als das Ergebnis in seinem Beispiel hat. Es wäre interessant, wenn Sie sein Beispiel erklären könnten. barlop vor 8 Jahren 0
-1 Sein Beispiel war Echo -e und doppelte Anführungszeichen. Dein hat kein "-e" barlop vor 8 Jahren 0
@Steven Ich möchte gerne sehen, "wie bash den Parameter ändert, der an das Echo gesendet wird", und sein Beispiel verwendet "-e" barlop vor 8 Jahren 0
@Steven Die Funktion des Echos unterscheidet sich mit und ohne -e, obwohl Ihre Erklärung dieselbe ist. Alles, was Sie getan haben, war, dass Sie das Ergebnis mit -e kopiert / eingefügt haben, und Ihre Erklärung blieb gleich. Und Sie haben nicht angegeben, ob Ihre Erklärung "Test \\ nNewline" durch Test \\ nNewline ersetzt wird. Da Ihre frühere Antwort den Fall ohne -e angab und Ihre neuere Antwort den Fall mit angibt, warum erklären Sie nicht für beide Fälle, anstatt Ihre Antwort so zu ändern, dass nur einer angezeigt wird. dh löschen Sie kein Beispiel aus Ihrer Antwort barlop vor 8 Jahren 0
@barlop Warum bearbeitest du die Antwort nicht so, wie du sie für richtig hältst? Steven vor 8 Jahren 0
Lassen Sie uns [diese Diskussion im Chat fortsetzen] (http://chat.stackexchange.com/rooms/26757/discussion-between-barlop-and-steven). barlop vor 8 Jahren 0
Lass uns nicht. Ich bin zufrieden mit meiner Antwort, so wie sie ist. Wenn nicht, bearbeiten Sie die Antwort. Sie haben den Ruf, dies zu tun. Steven vor 8 Jahren 0
2
Gordon Davisson

Steven hat bereits erklärt, warum so viele Backslashes notwendig sind. Ich möchte einige möglicherweise bessere Möglichkeiten auflisten, um dasselbe zu tun. Bei der Verwendung von einfachen Anführungszeichen anstelle von doppelten Anführungszeichen wird die zusätzliche Ebene der Escape-Interpretation / Entfernung übersprungen:

$ echo -e "Test\\\nNewline" Test\nNewline $ echo -e 'Test\\\nNewline' Test\ Newline 

Zweitens empfehle ich die Verwendung echofür solche Dinge, da sich verschiedene Versionen davon ganz unterschiedlich verhalten: Einige interpretieren Escape-Sequenzen in der Zeichenfolge (wie \nauch ohne die -eOption), andere geben das "-e" als Teil ihrer Ausgabe aus. usw. Hier ist ein Beispiel, das / bin / echo anstelle der bash-eingebauten Version verwendet:

$ /bin/echo -e 'Test\\\nNewline' -e Test\\\nNewline 

... das ist auf OS X v10.10.4; es kann sich je nach Betriebssystem und / oder Version unterscheiden. Immer wenn Sie vorhersagbares Verhalten mit Escape-Interpretation und / oder Abbruch des letzten Zeilenvorschubs wünschen, empfehle ich printfstatt echo. Es ist etwas komplizierter: Das erste Argument printfist ein Formatstring, in dem Escape- Zeichen immer interpretiert werden, und das kann auch %Sequenzen enthalten, die zum Hinzufügen der übrigen Argumente verwendet werden (in denen Escape-Sequenzen nicht interpretiert werden). Außerdem printffügt der Zeilenvorschub am Ende nicht automatisch hinzu. Sie müssen diesen explizit angeben. Hier sind einige Möglichkeiten, um zu drucken, was Sie möchten printf:

$ printf 'Test\\\nNewline\n' # note explicit final newline Test\ Newline $ printf '%s\n' 'Test\' 'Newline' # Escape is interpreted in the format string, but not in the second argument Test\ Newline 
Es ist zwar ärgerlich, dass sie zwar printf genannt haben, sich aber deutlich von der printf in C unterscheidet. Dies funktioniert zum Beispiel in C `printf ("% d "," A ");` es gibt 65 aus. Sie können $ printf '% s' 'A' machen, aber $ Printf '% d' 'A' nicht. barlop vor 8 Jahren 0
@ barlop Das ist nicht wirklich ein Unterschied in `printf`, es ist das Ergebnis der Shell, die nicht das gleiche Typsystem wie C verwendet. (Tatsächlich hat die Shell kein typisches System.) Sowohl in C als auch in der Shell erwartet die Formatspezifikation "% d" eine Ganzzahl, C und Bash haben jedoch sehr unterschiedliche Vorstellungen davon, was eine Ganzzahl ausmacht. In C ist "A" ein Zeichen, das ein ganzzahliger Typ ist, und hat den Wert 65. ("A" dagegen ist ein Array von Zeichen, was eine ganz andere Sache ist.) Bash hat nicht wirklich einen Integer-Typ, sondern nur Strings, aber ein aus Ziffern bestehender String ist auch eine Integer-Zahl. Gordon Davisson vor 8 Jahren 0
@barlop Nun, da ist das gesagt, es gibt einen Hack. Bashs `printf` behandelt eine Zeichenfolge, die mit einem einfachen Anführungszeichen beginnt, als Zeichen im C-Stil. `Printf '% d' '' A '' gibt also" 65 "aus. Gordon Davisson vor 8 Jahren 0
Wie weit gehen die Hacks zum Beispiel, wie wäre es mit einem Hack für diesen `printf ("% c ", 65);` Drucken von A barlop vor 8 Jahren 0
@ barlop Diese Richtung ist ickier. Sie müssen zwei Aufrufe von 'printf' verwenden: einen mit '% o', um sie in Oktal umzuwandeln. Nach einem umgekehrten Schrägstrich in einem zweiten Aufruf wird er als eine oktal-basierte Zeichen-Escape-Sequenz behandelt. `printf \\ $ (printf '% 03o' 65)` macht es. Weitere Informationen finden Sie unter [BashFAQ # 71: Wie konvertiere ich ein ASCII-Zeichen in seinen Dezimalwert (oder Hexadezimalwert) und zurück?] (Http://mywiki.wooledge.org/BashFAQ/071). Gordon Davisson vor 8 Jahren 0