sed kann das Zeilenumbruchzeichen nicht entfernen

12

Ich benutze es schon seit sedeiniger Zeit, aber hier ist eine Eigenart, mit der ich herumgekommen bin und die ich nicht lösen kann.

Lassen Sie mich mein Problem mit dem tatsächlichen Fall erklären.


Szene 1

printf "ls" | xclip -selection clipboard
echo "ls" | xclip -selection clipboard

Im ersten Befehl leite ich die printfAusgabe an weiter, xclipdamit sie in die Zwischenablage kopiert wird. Im printfGegensatz dazu echowird jetzt standardmäßig keine neue Zeile am Ende eingefügt. Wenn ich diesen Inhalt in das Terminal lseinfüge, wird der kopierte Befehl nicht automatisch ausgeführt.

In der zweiten Zeile befindet sich am Ende eine neue Zeile. Wenn Sie also den Inhalt der Zwischenablage einfügen, wird der Befehl auch in der Zwischenablage ausgeführt.

Das ist für mich unerwünscht. Also wollte ich die neue Zeile mit entfernen sed, aber es schlug fehl, wie in der folgenden Szene erläutert.

Szene 2

echo "ls" | sed -r 's/\n//g' | xclip -selection clipboard

Der Inhalt in der Zwischenablage enthält weiterhin Zeilenumbrüche. Wenn ich es in das Terminal einfüge, wird der Befehl automatisch ausgeführt.

Ich habe auch versucht, das Wagenrücklaufzeichen zu entfernen \r. Aber nada. Es scheint, dass mir hier etwas sehr Entscheidendes / Grundlegendes fehlt.

Shivams
quelle

Antworten:

16

sed\nBegrenzungen auf ewlines - sie werden bei der Eingabe immer entfernt und bei der Ausgabe wieder eingefügt. In einem Musterbereich befindet sich niemals ein \nEwline-Zeichen sed, das nicht aufgrund einer von Ihnen vorgenommenen Bearbeitung aufgetreten ist . Hinweis: Mit Ausnahme des GNU sed- -zModus ...

Verwenden Sie einfach tr:

echo ls | tr -d \\n | xclip -selection clipboard

Oder, noch besser, sedganz vergessen :

printf ls | xclip -selection clipboard
mikeserv
quelle
Dadurch werden alle Zeilenumbrüche entfernt, die in diesem generate-text | xclipFall häufig nicht erwünscht sind . Diese Antwort entfernt nur den letzten Zeilenumbruch.
Tom Hale
7

Viele Textverarbeitungswerkzeuge, einschließlich sed, arbeiten mit dem Inhalt der Zeile, mit Ausnahme des Zeilenumbruchzeichens. Das erste, was sed bei der Verarbeitung einer Zeile tut, ist, die neue Zeile am Ende zu entfernen, dann die Befehle im Skript auszuführen und beim Ausdrucken eine letzte neue Zeile hinzuzufügen. Sie können die Newline also nicht mit sed entfernen.

Um alle Zeilenumbrüche zu entfernen, können Sie trstattdessen Folgendes verwenden :

echo "ls" | tr -d '\n' | xclip

Gilles 'SO - hör auf böse zu sein'
quelle
4

Sie können Zeilenumbrüche in sed ersetzen, indem Sie die Option -z übergeben .

sed -z 's/\n/ /g'

Sed Manpage:

-z, --null-data trennt Zeilen durch NUL-Zeichen

JSON C11
quelle
Dadurch werden alle Zeilenumbrüche entfernt, was in diesem | xclipFall im Allgemeinen nicht erwünscht ist.
Tom Hale
2

Wenn Sie nur Befehle in die Zwischenablage einfügen

echo -n "ls " | xclip -selection clipboard

Wenn Sie zusätzlich komplexere Transformationen vornehmen müssen,

echo "ls  " | perl -pe 's/\n//' | xclip -selection clipboard
JJoao
quelle
Hmm. Glatte Lösung. Ich denke, es ist vielleicht an der Zeit, für Regex zu Perl oder Python zu wechseln.
Shivams
3
@shivams - perlund pythonbeide sind viel langsamer als sedbei korrekter Verwendung. Das Erlernen des richtigen Gebrauchs ist jedoch der Schlüssel.
Mikeserv
@mikeserv - ich stimme zu; speziell für oneliner sed ist wunderbar. Wenn die Transformationen komplexer werden, bevorzuge ich Perl / Python / Gawk.
JJoao
1
@JJoa: Ihre Präferenz ist Ihre eigene, sedkann aber weit mehr als nur Ihre Einzeiler handhaben, und dies kann wahrscheinlich schneller als jedes der anderen Tools, die Sie erwähnen.
Mikeserv
1
@mikeserv - noch einmal, ich stimme dir zu. Vor einigen Jahren hatte ich ein Übersetzungssystem EN-PT in sed (20000 s /.../.../) geschrieben, das von sed generiert wurde! Und es hat funktioniert! Später wurde es Perl, Arrays, Hashes, Funktionen, Pakete und CPAN zu haben.
JJoao
1

Um nur die letzte neue Zeile zu entfernen, führen Sie Folgendes durch:

sed -z '$ s/\n$//'

sedfügt kein \0bis zum Ende des Streams hinzu, wenn das Trennzeichen auf NULvia gesetzt ist -z, während beim Erstellen einer POSIX-Textdatei (definiert als Ende in a \n) immer ein Finale \nohne ausgegeben wird -z.

Z.B:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender

Und um nicht NULhinzugefü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+$//'
Tom Hale
quelle