Wenn ich Befehle in Bash ausführe (oder genauer gesagt wc -l < log.txt
), enthält die Ausgabe einen Zeilenumbruch danach. Wie werde ich es los?
Wenn ich Befehle in Bash ausführe (oder genauer gesagt wc -l < log.txt
), enthält die Ausgabe einen Zeilenumbruch danach. Wie werde ich es los?
Antworten:
Wenn Ihre erwartete Ausgabe eine einzelne Zeile ist , können Sie einfach alle Zeilenumbrüche aus der Ausgabe entfernen. Es ist nicht ungewöhnlich, an das Dienstprogramm 'tr' oder, falls bevorzugt, an Perl weiterzuleiten:
wc -l < log.txt | tr -d '\n'
wc -l < log.txt | perl -pe 'chomp'
Sie können auch die Befehlsersetzung verwenden, um die nachfolgende neue Zeile zu entfernen:
echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"
Bitte beachten Sie, dass ich mit der Entscheidung des OP, die akzeptierte Antwort zu wählen, nicht einverstanden bin. Ich glaube, man sollte es nach Möglichkeit vermeiden, 'xargs' zu verwenden. Ja, es ist ein cooles Spielzeug. Nein, das brauchst du hier nicht.
Wenn Ihre erwartete Ausgabe mehrere Zeilen enthalten kann , müssen Sie eine andere Entscheidung treffen:
Wenn Sie MEHRERE Zeilenumbrüche am Ende der Datei entfernen möchten, verwenden Sie erneut die cmd-Ersetzung:
printf "%s" "$(< log.txt)"
Wenn Sie das letzte Zeilenumbruchzeichen strikt aus einer Datei entfernen möchten, verwenden Sie Perl:
perl -pe 'chomp if eof' log.txt
Beachten Sie, dass Sie, wenn Sie sicher sind, dass Sie ein nachfolgendes Zeilenumbruchzeichen entfernen möchten, mit 'head' von GNU coreutils alles außer dem letzten Byte auswählen können. Das sollte ziemlich schnell gehen:
head -c -1 log.txt
Der Vollständigkeit halber können Sie mit 'cat' und dem Flag 'show-all' schnell überprüfen, wo sich Ihre Zeilenumbrüche (oder andere Sonderzeichen) in Ihrer Datei befinden. Das Dollarzeichen gibt das Ende jeder Zeile an:
cat -A log.txt
tr --delete '\n'
.
| tr -d '\r'
Einweg:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
IFS
) auf ein Leerzeichen. Beispiel : echo "a b" | xargs echo -n
; echo -n $(echo "a b")
. Dies kann für den Anwendungsfall ein Problem sein oder auch nicht.
-e
, wird sie als Option für interpretiert echo
. Es ist immer sicherer zu bedienen printf '%s'
.
xargs
ist auf meinem System sehr langsam (und ich vermute, dass es auch auf anderen Systemen ist), kann printf '%s' $(wc -l log.txt)
also schneller sein, da printf
es normalerweise ein eingebautes System ist (auch weil es keine Informationsumleitung gibt). Verwenden Sie niemals Backticks, diese sind in neueren POSIX-Versionen veraltet und weisen zahlreiche Nachteile auf.
Es gibt auch direkte Unterstützung für das Entfernen von Leerzeichen bei der Substitution von Bash-Variablen :
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
Wenn Sie die Ausgabe einer Variablen zuweisen, bash
werden Leerzeichen automatisch entfernt:
linecount=`wc -l < log.txt`
printf schneidet bereits die nachfolgende Newline für Sie ab:
$ printf '%s' $(wc -l < log.txt)
Detail:
%s
String-Platzhalters. %s\n
) drucken soll , wird dies nicht der Fall sein ."$(command)"
, werden die internen Zeilenumbrüche bewahrt werden - und nur die hintere Newline entfernt werden. Die Shell erledigt hier die ganze Arbeit - printf
ist nur eine Möglichkeit, die Ergebnisse der Befehlssubstitution zurück zu leiten stdout
.
$( )
Konstrukt tut . Hier ist der Beweis:printf "%s" "$(perl -e 'print "\n"')"
$ printf '%s' "$(wc -l < log.txt)"
Wenn Sie nur die letzte neue Zeile entfernen möchten, leiten Sie Folgendes durch:
sed -z '$ s/\n$//'
sed
fügt kein \0
bis zum Ende des Streams hinzu, wenn das Trennzeichen auf NUL
via gesetzt ist -z
, während beim Erstellen einer POSIX-Textdatei (definiert als Ende in a \n
) immer ein Finale \n
ohne ausgegeben wird -z
.
Z.B:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
Und um nicht NUL
hinzugefügt zu beweisen :
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
Um mehrere nachfolgende Zeilenumbrüche zu entfernen, führen Sie Folgendes durch:
sed -Ez '$ s/\n+$//'
sed
nicht bietet -z
.
Wenn Sie die Ausgabe von etwas in Bash ohne Zeilenende drucken möchten, geben Sie dies mit dem -n
Schalter wieder.
Wenn Sie es bereits in einer Variablen haben, geben Sie es mit der abgeschnittenen neuen Zeile wieder :
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Oder Sie können es stattdessen in einer Zeile tun:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)
hat den gleichen Effekt.