1729 Stimmen

Wie kann ich jeden Zeilenumbruch ( \n ) mit einem Leerzeichen mit sed?

Wie kann ich einen Zeilenumbruch (" \n ") mit einem Leerzeichen (" ") unter Verwendung der sed Befehl?

Ich habe es erfolglos versucht:

sed 's#\n# #g' file
sed 's#^$# #g' file

Wie kann ich es reparieren?

2033voto

sed ist für die Verwendung mit leitungsgebundenen Eingängen vorgesehen. Obwohl es tun kann, was Sie brauchen.


Eine bessere Option ist hier die Verwendung der tr Befehl wie folgt:

tr '\n' ' ' < input_filename

oder entfernen Sie die Zeilenumbruchzeichen ganz:

tr -d '\n' < input.txt > output.txt

oder wenn Sie die GNU-Version (mit ihren langen Optionen) haben

tr --delete '\n' < input.txt > output.txt

1794voto

Zsolt Botykai Punkte 48177

Verwenden Sie diese Lösung mit GNU sed :

sed ':a;N;$!ba;s/\n/ /g' file

Damit wird die gesamte Datei in einer Schleife gelesen ( ':a;N;$!ba ) und ersetzt dann den/die Zeilenumbruch/e durch ein Leerzeichen ( s/\n/ /g ). Weitere Ersetzungen können bei Bedarf einfach angefügt werden.

Erläuterung:

  1. sed beginnt mit dem Einlesen der ersten Zeile ohne den Zeilenumbruch in den Musterbereich.
  2. Erstellen Sie ein Etikett über :a .
  3. Anhängen eines Zeilenumbruchs und der nächsten Zeile an den Musterbereich über N .
  4. Wenn wir uns vor der letzten Zeile befinden, verzweigen wir zu dem erstellten Etikett $!ba ( $! bedeutet, dass dies nicht in der letzten Zeile geschehen soll. Dies ist notwendig, um die Ausführung von N was das Skript beenden würde, wenn es keine weitere Eingabe gibt!).
  5. Schließlich wird bei der Ersetzung jeder Zeilenumbruch durch ein Leerzeichen im Musterbereich (d. h. in der gesamten Datei) ersetzt.

Hier ist die plattformübergreifende Syntax, die mit BSD und OS X funktioniert sed (gemäß @Benjie Kommentar ):

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file

Wie Sie sehen können, ist die Verwendung von sed für dieses ansonsten einfache Problem ist problematisch. Für eine einfachere und angemessene Lösung siehe diese Antwort .

617voto

hdorio Punkte 12232

Schnelle Antwort

sed ':a;N;$!ba;s/\n/ /g' file
  1. :a ein Etikett 'a' erstellen
  2. N die nächste Zeile an den Musterbereich anhängen
  3. $! wenn nicht die letzte Zeile , ba Verzweigung (Gehe zu) Etikett 'a'
  4. s Ersatz , / \n / Regex für neue Zeile , / / durch ein Leerzeichen , /g globale Übereinstimmung (so oft wie möglich)

sed durchläuft die Schritte 1 bis 3 in einer Schleife, bis es die letzte Zeile erreicht hat und alle Zeilen in den Musterbereich passen, wo sed alle \n Zeichen


Alternativen

Alle Alternativen, im Gegensatz zu sed die letzte Zeile nicht erreichen müssen, um den Prozess zu beginnen

avec bash , langsam

while read line; do printf "%s" "$line "; done < file

avec perl , sed -ähnliche Geschwindigkeit

perl -p -e 's/\n/ /' file

avec tr , schneller als sed , kann nur durch ein Zeichen ersetzt werden

tr '\n' ' ' < file

avec einfügen , tr -wie Geschwindigkeit, kann nur durch ein Zeichen ersetzt werden

paste -s -d ' ' file

avec awk , tr -ähnliche Geschwindigkeit

awk 1 ORS=' ' file

Andere Alternativen wie "echo $(< Datei)" ist langsam, funktioniert nur bei kleinen Dateien und muss die gesamte Datei verarbeiten, um den Prozess zu starten.


Lange Antwort des sed FAQ 5.10

5.10. Warum kann ich einen Zeilenumbruch nicht mit der Funktion \n Flucht
Sequenz? Warum kann ich nicht 2 oder mehr Zeilen mit \n ?

El \n wird nie mit dem Zeilenumbruch am Zeilenende übereinstimmen, da die
wird der Zeilenumbruch immer entfernt, bevor die Zeile in den
Musterraum. Um 2 oder mehr Zeilen in den Musterbereich zu bekommen, verwenden Sie
den Befehl "N" oder etwas Ähnliches (wie "H;...;g;").

Sed funktioniert folgendermaßen: sed liest eine Zeile nach der anderen, schneidet die
abschließenden Zeilenumbruch, setzt den Rest in den Musterbereich, wo
kann das sed-Skript es adressieren oder ändern, und wenn der Musterraum
gedruckt wird, wird ein Zeilenumbruch an stdout (oder an eine Datei) angehängt. Wenn die
Musterraum ganz oder teilweise mit 'd' oder 'D' gelöscht wird, wird der
Zeilenumbruch ist pas in solchen Fällen hinzugefügt. So können Skripte wie

  sed 's/\n//' file       # to delete newlines from each line             
  sed 's/\n/foo\n/' file  # to add a word to the end of each line         

wird NIEMALS funktionieren, da der abschließende Zeilenumbruch entfernt wird vor
wird die Zeile in den Musterbereich gesetzt. So führen Sie die oben genannten Aufgaben aus,
verwenden Sie stattdessen eines dieser Skripte:

  tr -d '\n' < file              # use tr to delete newlines              
  sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines             
  sed 's/$/ foo/' file           # add "foo" to end of each line          

Da andere Versionen von sed als GNU sed Grenzen für die Größe von
des Musterpuffers ist hier das Unix-Dienstprogramm "tr" vorzuziehen.
Wenn die letzte Zeile der Datei einen Zeilenumbruch enthält, fügt GNU sed
den Zeilenumbruch in die Ausgabe, löscht aber alle anderen, während tr
alle Zeilenumbrüche löschen.

Um einen Block aus zwei oder mehr Zeilen anzupassen, gibt es 3 grundlegende Möglichkeiten:
(1) Verwenden Sie den Befehl "N", um die nächste Zeile in den Musterbereich einzufügen;
(2) Verwenden Sie den Befehl 'H' mindestens zweimal, um die aktuelle Zeile anzuhängen
in den Hold-Bereich, und rufen Sie dann die Zeilen aus dem Hold-Bereich ab
mit x, g oder G; oder (3) Adressbereiche verwenden (siehe Abschnitt 3.3, oben)
um Zeilen zwischen zwei angegebenen Adressen abzugleichen.

Die Optionen (1) und (2) führen zu einer \n in den Musterraum, wo es
kann beliebig adressiert werden ('s/ABC \nXYZ /alphabet/g'). Ein Beispiel
Die Verwendung von "N" zum Löschen eines Zeilenblocks wird in Abschnitt 4.13 beschrieben.
("Wie lösche ich einen Block von spezifisch aufeinanderfolgende Zeilen?"). Diese
Beispiel kann geändert werden, indem der Löschbefehl in etwas anderes geändert wird
sonst, wie 'p' (drucken), 'i' (einfügen), 'c' (ändern), 'a' (anhängen),
oder 's' (Ersatz).

Bei Wahlmöglichkeit (3) wird kein \n in den Musterraum, aber es tut
mit einem Block aufeinanderfolgender Zeilen übereinstimmen, so dass es sein kann, dass Sie nicht
brauchen sogar die \n um zu finden, was Sie suchen. Da GNU sed
Version 3.02.80 unterstützt nun diese Syntax:

  sed '/start/,+4d'  # to delete "start" plus the next 4 lines,           

zusätzlich zum traditionellen "/von hier/,/nach dort/{...}"-Bereich
Adressen, ist es möglich, die Verwendung von \n vollständig.

270voto

JJoao Punkte 4381

GNU sed hat eine Option, -z für null-getrennte Datensätze (Zeilen). Sie können einfach aufrufen:

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

254voto

Thor Punkte 42021

Eine kürzere awk-Alternative:

awk 1 ORS=' '

Erläuterung

Ein awk-Programm ist aus Regeln aufgebaut, die aus bedingten Code-Blöcken bestehen, d.h.:

condition { code-block }

Wird der Code-Block weggelassen, wird der Standardwert verwendet: { print $0 } . Daher ist die 1 wird als wahre Bedingung interpretiert und print $0 wird für jede Zeile ausgeführt.

Wenn awk die Eingabe liest, wird sie in Datensätze aufgeteilt, die auf dem Wert von RS (Satztrennzeichen), das standardmäßig ein Zeilenumbruch ist, also awk wird die Eingabe standardmäßig zeilenweise geparst. Die Aufteilung beinhaltet auch das Entfernen von RS aus dem Eingabesatz.

Wenn Sie jetzt einen Datensatz drucken, ORS (Output Record Separator) angehängt, Standard ist wieder ein Zeilenumbruch. Wenn Sie also die ORS zu einem Leerzeichen werden alle Zeilenumbrüche in Leerzeichen umgewandelt.

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