Warum ist dies als Betrug markiert? Bei dieser Frage geht es um das Entfernen eines Wagenrücklaufs. Die angebliche doppelte Frage, auf die verwiesen wird, betrifft das Entfernen von Leerzeichen und erwähnt nur beiläufig Wagenrückläufe.
Michael Scheper
1
@ MichaelScheper stimmte zu und öffnete wieder.
Fedorqui 'SO hör auf zu schaden'
Die Terminologie hier ist seltsam. Das Unix- \nZeilenabschlusszeichen (hex 0x0A) wird als Lügenvorschub (LF) bezeichnet. Es unterscheidet sich vom CR \r( Character Carriage Return) (hex 0x0D), der unter Windows und in vielen Netzwerkprotokollen als erstes Byte in der Zwei-Byte-Zeilenendsequenz CR LF verwendet wird.
Auf diese Weise können Zeilenvorschübe von einer Variablen in BASH entfernt werden. Andere Antworten rufen unnötigerweise einen zusätzlichen TR-Prozess auf. Übrigens hat es den zusätzlichen Vorteil, Endräume zu entfernen!
Ingyhere
1
Beachten Sie, dass es auch interne Leerzeichen aus einer Zeichenfolge entfernt ... COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"kehrt zurück|REBOOT|
Alex Jordan
2
@AlexJordan Ja, es ist eine gewünschte Funktion : Sie können das Leerzeichen nachher löschen \n, um dies zu verhindern: COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"wird zurückkehren |RE BOOT|.
F. Hauri
2
Wie funktioniert das Muster ${COMMAND//[$'\t\r\n']}? Ich dachte, es ${COMMAND//[\t\r\n]}würde einfach funktionieren, aber das tat es nicht. Wofür ist das $Symbol und auch die einfachen Anführungszeichen?
Haridsv
1
In Bezug auf die $ '' - Syntax ist dies ANSI C-Zitat (in der Antwort von wjordans erwähnt).
Chuckx
81
echo "|$COMMAND|"|tr '\n'' '
ersetzt die neue Zeile (in POSIX / Unix ist es kein Wagenrücklauf) durch ein Leerzeichen.
Um ehrlich zu sein, würde ich darüber nachdenken, von Bash zu etwas Vernünftigerem zu wechseln. Oder vermeiden Sie es, diese fehlerhaften Daten überhaupt zu generieren.
Hmmm, dies scheint auch eine schreckliche Sicherheitslücke zu sein, je nachdem, woher die Daten stammen.
Das Datum stammt von einer Curl-Anfrage, die sich auf demselben Server befindet. Wie würde ich das in eine neue Variable einfügen? newvar = $ (echo "| $ COMMAND |" | tr '\ n' '')
Matt Leyland
2
Ja. Aber bitte sagen Sie mir, dass Sie nicht
Robin Green
31
Warum haben Sie nicht verwendet, tr -d '\n'um zu fallen, anstatt durch ein Leerzeichen zu ersetzen
F. Hauri
3
Bitte peitschen Sie nutzlose Rohre! Verwenden Sie tr '\n' ' ' <<< "|$COMMAND|"anstelle vonecho ... | ...
F. Hauri
12
@ F.Hauri: oder nutzlose tr's:"|${COMMAND//$'\n'}|"
Rici
75
Bereinigen Sie Ihre Variable, indem Sie alle Wagenrückläufe entfernen:
Streift das nicht Linefeeds? Sollte es nicht tr -d '\r'stattdessen sein?
Izzy
3
Durch das Echo einer nicht kommentierten Variablen werden alle IFS-Zeichen entfernt (Zeilenumbruch, Leerzeichen, Tabulator standardmäßig). Wenn Sie dies tun, sollten Sie sich darüber im Klaren sein, dass alle IFS-Zeichen gelöscht werden und Sie das nicht benötigen tr. Einfach COMMAND=$(echo $COMMAND)wird ein ähnlicher Effekt geben. Das ist vermutlich Teufelsbrut, da es einen neuen Prozess auslöst, aber es ist immer noch ziemlich kurz und süß für die Augen des Menschen, und wenn Sie ein oder zwei Sekunden in Ihrem Leben übrig haben, sind Sie möglicherweise bereit, den Treffer zu nehmen :-).
Mike S
Ich habe die Frage mit "Zeilenvorschub" aktualisiert, da das Beispiel gezeigt hat, dass es sich um einen Zeilenvorschub handelt, nicht um einen Wagenrücklauf. Diese Antwort ist immer noch richtig, sollte aber möglicherweise aktualisiert werden, um "Zeilenvorschub" anstelle von "Wagenrücklauf" zu sagen?
Benjamin W.
8
Verwenden von bash:
echo "|${COMMAND/$'\n'}|"
(Beachten Sie, dass das Steuerzeichen in dieser Frage eine 'Newline' ( \n) und kein Wagenrücklauf ( \r) ist. Letzteres würde REBOOT|in einer einzelnen Zeile ausgegeben .)
Das Muster wird erweitert, um ein Muster wie bei der Dateinamenerweiterung zu erzeugen. Der Parameter wird erweitert und die längste Übereinstimmung des Musters mit seinem Wert wird durch eine Zeichenfolge ersetzt . [...] Wenn Zeichenfolge null ist, Spiele von Mustern werden gelöscht und die / folgenden Muster weggelassen werden können.
Verwendet auch das $''ANSI-C- Anführungszeichenkonstrukt, um eine neue Zeile als anzugeben $'\n'. Die direkte Verwendung eines Zeilenumbruchs würde ebenfalls funktionieren, wenn auch weniger hübsch:
Hinzufügen einer Antwort, um ein Beispiel für das Entfernen mehrerer Zeichen zu zeigen, einschließlich \ r mit tr und sed. Und mit Hexdump veranschaulichen.
In meinem Fall hatte ich festgestellt, dass ein Befehl, der mit awk print des letzten Elements |awk '{print $2}'in der Zeile endet, einen Wagenrücklauf sowie Anführungszeichen enthielt.
Ich habe sed 's/["\n\r]//g'sowohl den Wagenrücklauf als auch die Anführungszeichen entfernt.
Ich hätte es auch gebrauchen können tr -d '"\r\n'.
Interessant zu beachten sed -zist, wenn man \ n Zeilenvorschubzeichen entfernen möchte.
\n
Zeilenabschlusszeichen (hex 0x0A) wird als Lügenvorschub (LF) bezeichnet. Es unterscheidet sich vom CR\r
( Character Carriage Return) (hex 0x0D), der unter Windows und in vielen Netzwerkprotokollen als erstes Byte in der Zwei-Byte-Zeilenendsequenz CR LF verwendet wird.Antworten:
Unter Bashgibt es einige Bashismen:
Der
tr
Befehl könnte durch//
Bashismus ersetzt werden :Siehe Parametererweiterung und QUOTING in der Manpage von bash:
Des Weiteren...
Auf Anfrage von @AlexJordan werden dadurch alle angegebenen Zeichen unterdrückt . Was ist, wenn
$COMMAND
Leerzeichen enthalten sind?In Kürze:
Hinweis: Bashhat
extglob
Option wird (aktiviertshopt -s extglob
) zu verwenden , um*(...)
Syntax.quelle
COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"
kehrt zurück|REBOOT|
\n
, um dies zu verhindern:COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"
wird zurückkehren|RE BOOT|
.${COMMAND//[$'\t\r\n']}
? Ich dachte, es${COMMAND//[\t\r\n]}
würde einfach funktionieren, aber das tat es nicht. Wofür ist das$
Symbol und auch die einfachen Anführungszeichen?ersetzt die neue Zeile (in POSIX / Unix ist es kein Wagenrücklauf) durch ein Leerzeichen.
Um ehrlich zu sein, würde ich darüber nachdenken, von Bash zu etwas Vernünftigerem zu wechseln. Oder vermeiden Sie es, diese fehlerhaften Daten überhaupt zu generieren.
Hmmm, dies scheint auch eine schreckliche Sicherheitslücke zu sein, je nachdem, woher die Daten stammen.
quelle
tr -d '\n'
um zu fallen, anstatt durch ein Leerzeichen zu ersetzentr '\n' ' ' <<< "|$COMMAND|"
anstelle vonecho ... | ...
"|${COMMAND//$'\n'}|"
Bereinigen Sie Ihre Variable, indem Sie alle Wagenrückläufe entfernen:
quelle
tr -d '\r'
stattdessen sein?tr
. EinfachCOMMAND=$(echo $COMMAND)
wird ein ähnlicher Effekt geben. Das ist vermutlich Teufelsbrut, da es einen neuen Prozess auslöst, aber es ist immer noch ziemlich kurz und süß für die Augen des Menschen, und wenn Sie ein oder zwei Sekunden in Ihrem Leben übrig haben, sind Sie möglicherweise bereit, den Treffer zu nehmen :-).Verwenden von
bash
:(Beachten Sie, dass das Steuerzeichen in dieser Frage eine 'Newline' (
\n
) und kein Wagenrücklauf (\r
) ist. Letzteres würdeREBOOT|
in einer einzelnen Zeile ausgegeben .)Erläuterung
Verwendet die Bash Shell-Parametererweiterung
${parameter/pattern/string}
:Verwendet auch das
$''
ANSI-C- Anführungszeichenkonstrukt, um eine neue Zeile als anzugeben$'\n'
. Die direkte Verwendung eines Zeilenumbruchs würde ebenfalls funktionieren, wenn auch weniger hübsch:Vollständiges Beispiel
Oder mit Zeilenumbrüchen:
quelle
Was für mich funktioniert hat war
echo $testVar | tr "\n" " "
Wo testVar meine Variablen- / Skriptausgabe enthielt
quelle
Hinzufügen einer Antwort, um ein Beispiel für das Entfernen mehrerer Zeichen zu zeigen, einschließlich \ r mit tr und sed. Und mit Hexdump veranschaulichen.
In meinem Fall hatte ich festgestellt, dass ein Befehl, der mit awk print des letzten Elements
|awk '{print $2}'
in der Zeile endet, einen Wagenrücklauf sowie Anführungszeichen enthielt.Ich habe
sed 's/["\n\r]//g'
sowohl den Wagenrücklauf als auch die Anführungszeichen entfernt.Ich hätte es auch gebrauchen können
tr -d '"\r\n'
.Interessant zu beachten
sed -z
ist, wenn man \ n Zeilenvorschubzeichen entfernen möchte.Und das ist relevant: Was sind Wagenrücklauf, Zeilenvorschub und Formularvorschub?
quelle
Sie können einfach verwenden
echo -n "|$COMMAND|"
.quelle
Wenn Sie bash mit aktivierter extglob-Option verwenden, können Sie nur das nachfolgende Leerzeichen entfernen über:
Dies gibt aus:
Oder ersetzen Sie %% durch ##, um nur das führende Leerzeichen zu ersetzen.
quelle