Frage Wie kann ich eine neue Zeile (\ n) mit sed ersetzen?


Wie kann ich eine neue Zeile ersetzen (\n) mit dem Befehl sed?

Ich habe erfolglos versucht:

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

Wie repariere ich es?


1125
2017-08-09 19:10


Ursprung


Antworten:


Verwenden Sie diese Lösung mit GNU sed:

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

Dies liest die gesamte Datei in einer Schleife und ersetzt dann die Zeilenschaltung durch ein Leerzeichen.

Erläuterung:

  1. Erstellen Sie ein Label über :a.
  2. Fügen Sie die aktuelle und nächste Zeile über den Musterbereich an N.
  3. Wenn wir vor der letzten Zeile sind, verzweigen Sie zum erstellten Label $!ba ($! bedeutet, es nicht in der letzten Zeile zu tun, da es eine letzte Zeile geben sollte).
  4. Schließlich ersetzt die Substitution jede neue Zeile durch ein Leerzeichen im Musterbereich (also die gesamte Datei).

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

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

1278
2017-08-09 20:26



Benutzen tr stattdessen?

tr '\n' ' ' < input_filename

oder entfernen Sie die Zeilenumbruchzeichen vollständig:

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

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

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

1447
2017-08-09 19:16



Schnelle Antwort:

sed ':a;N;$!ba;s/\n/ /g' file
  1. :ein  Erstellen Sie ein Label "a"
  2. N  Hängen Sie die nächste Zeile an den Musterbereich an
  3. $!  wenn nicht die letzte Zeile, ba  Zweig (gehe zu) Label '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, bis die letzte Zeile erreicht ist, und alle Zeilen in den Musterbereich passen, wobei sed alle \ n Zeichen ersetzt


Alternativen:

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

mit bash, langsam

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

mit Perl, sedwie Geschwindigkeit

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

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

tr '\n' ' ' < file

mit Einfügen, trähnliche Geschwindigkeit, kann nur durch ein Zeichen ersetzt werden

paste -s -d ' ' file

mit awk, trwie Geschwindigkeit

awk 1 ORS=' ' file

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


Lange Antwort von dem sed FAQ 5.10:

5.10. Warum kann ich einen Zeilenumbruch nicht mit dem \ n Escape-Zeichen abgleichen oder löschen
      Sequenz? Warum kann ich 2 oder mehr Zeilen nicht mit \ n kombinieren?

Das \ n wird nie am Zeilenende mit dem Zeilenumbruch übereinstimmen, da der
   newline wird immer ausgezogen, bevor die Zeile in die gelegt wird
   Musterraum. Um 2 oder mehr Zeilen in den Musterbereich zu bekommen, verwenden Sie
   der 'N'-Befehl oder etwas ähnliches (wie' H; ...; g; ').

Sed funktioniert wie folgt: sed liest eine Zeile nach der anderen, löscht die
   Beenden von Newline, legt, was in dem Musterraum wo bleibt
   Das sed-Skript kann es adressieren oder ändern und wenn der Musterraum
   gedruckt wird, hängt eine neue Zeile an stdout (oder an eine Datei) an. Wenn die
   Der Musterraum wird ganz oder teilweise mit 'd' oder 'D' gelöscht
Newline ist nicht hinzugefügt in solchen Fällen. Also, 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, weil der abschließende Zeilenumbruch entfernt wird Vor
   Die Linie wird in den Musterraum gelegt. Um die oben genannten Aufgaben auszuführen,
   Verwenden Sie stattdessen eines dieser Skripts:

  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          

Seit Versionen von sed außer GNU sed haben Grenzen für die Größe von
   der Musterpuffer, das Unix-Dienstprogramm 'tr' ist hier zu bevorzugen.
   Wenn die letzte Zeile der Datei einen Zeilenumbruch enthält, wird GNU sed hinzugefügt
   diese Newline zum Ausgang aber alle anderen löschen, während tr wird
   lösche alle Zeilenumbrüche.

Um einem Block aus zwei oder mehr Zeilen zu entsprechen, gibt es drei grundlegende Auswahlmöglichkeiten:
   (1) Verwenden Sie den Befehl 'N', um die nächste Zeile zum Musterbereich hinzuzufügen;
   (2) Verwenden Sie den Befehl 'H' mindestens zweimal, um die aktuelle Zeile anzufügen
   in das Feld "Halten" und rufen Sie dann die Zeilen aus dem Speicherbereich ab
   mit x, g oder G; oder (3) Adressbereiche verwenden (siehe Abschnitt 3.3, oben)
   Übereinstimmungen zwischen zwei angegebenen Adressen.

Mit den Optionen (1) und (2) wird ein \ n in den Musterraum eingefügt, in dem es sich befindet
   kann wie gewünscht adressiert werden ('s / ABC \ nXYZ / alphabet / g'). Ein Beispiel
   Die Verwendung von 'N' zum Löschen eines Zeilenblocks erscheint in Abschnitt 4.13
   (Wie lösche ich einen Block von Spezifisch aufeinanderfolgenden Zeilen? ")
   Beispiel kann geändert werden, indem der Löschbefehl in etwas geändert wird
   sonst, wie 'p' (drucken), 'i' (einfügen), 'c' (ändern), 'a' (append),
   oder 's' (stellvertretend).

Choice (3) wird kein \ n in den Musterraum einfügen, aber es tut
   Passen Sie einen Block aufeinander folgender Zeilen an, es könnte also sein, dass Sie dies nicht tun
   Sie brauchen sogar \ n, um zu finden, wonach Sie suchen. Seit GNU sed
   Version 3.02.80 unterstützt jetzt diese Syntax:

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

zusätzlich zu den traditionellen '/ von hier /, / zu dort / {...}' Bereich
   Adressen, kann es möglich sein, die Verwendung von \ n vollständig zu vermeiden.


412
2017-10-08 14:55



Eine kürzere awk Alternative:

awk 1 ORS=' '

Erläuterung

Ein awk-Programm besteht aus Regeln, die aus bedingten Code-Blöcken bestehen, nämlich:

condition { code-block }

Wenn der Codeblock weggelassen wird, wird der Standardwert verwendet: { print $0 }. Und so kam es dass der 1 wird als eine wahre Bedingung interpretiert und print $0 wird für jede Zeile ausgeführt.

Wann awk liest die Eingabe es teilt es in Datensätze basierend auf dem Wert von RS (Record Separator), das standardmäßig ein Newline ist awk wird standardmäßig die Eingabe zeilenweise analysieren. Die Spaltung beinhaltet auch das Abziehen RS aus dem Eingabesatz.

Jetzt, beim Drucken eines Datensatzes, ORS (Output Record Separator) wird daran angehängt (Standard ist wiederum ein Newline). Also durch Veränderung ORSIn ein Leerzeichen werden alle Zeilenumbrüche in Leerzeichen geändert.


175
2018-02-13 12:12



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

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

91
2018-05-05 09:43



Das Perl Version funktioniert so, wie Sie es erwartet haben.

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

Wie in den Kommentaren erwähnt, ist es erwähnenswert, dass diese Änderungen vorhanden sind. -i.bak wird Ihnen vor dem Austausch eine Sicherungskopie der Originaldatei zur Verfügung stellen regulären Ausdruck ist nicht so schlau wie du dachtest.


75
2017-08-09 19:25



Wer braucht sed? Hier ist das bash Weg:

cat test.txt |  while read line; do echo -n "$line "; done

40
2017-08-11 12:07



Um alle Zeilenumbrüche durch awk mit Leerzeichen zu ersetzen, ohne die gesamte Datei im Speicher zu lesen:

awk '{printf "%s ", $0}' inputfile

Wenn Sie eine letzte Zeilenumschaltung wünschen:

awk '{printf "%s ", $0} END {printf "\n"}' inputfile

Sie können ein anderes Zeichen als Leerzeichen verwenden:

awk '{printf "%s|", $0} END {printf "\n"}' inputfile

23
2018-03-30 06:41



Drei Dinge.

  1. tr (oder catusw.) wird absolut nicht benötigt. (GNU) sed und (GNU) awk, wenn kombiniert, kann 99,9% der Textverarbeitung, die Sie benötigen, tun.

  2. stream! = linienbasiert. ed ist ein zeilenbasierter Editor. sed ist nicht. Sehen sed Vortrag für mehr Informationen über den Unterschied. Die meisten Leute verwirren sed linienbasiert sein, da es standardmäßig nicht sehr gierig in seinem Mustervergleich für SIMPLE-Matches ist - zum Beispiel, wenn es Mustersuchen und Ersetzen durch ein oder zwei Zeichen durchführt, ersetzt es standardmäßig nur das erste gefundene Match ( sofern nicht anders durch den globalen Befehl angegeben). Es würde nicht einmal einen globalen Befehl geben, wenn er statt STREAM-basiert linienbasiert wäre, weil er nur Zeilen auf einmal auswerten würde. Versuche zu laufen ed; Sie werden den Unterschied bemerken. ed ist sehr nützlich, wenn Sie über bestimmte Zeilen (z. B. in einer For-Schleife) iterieren möchten, aber die meisten Male wollen Sie nur sed.

  3. Davon abgesehen,

    sed -e '{:q;N;s/\n/ /g;t q}' file
    

    funktioniert gut in GNU sed Version 4.2.1. Der obige Befehl ersetzt alle Zeilenumbrüche durch Leerzeichen. Es ist hässlich und ein bisschen umständlich zu tippen, aber es funktioniert gut. Das {}'s können weggelassen werden, da sie nur aus Gründen der Gesundheit enthalten sind.


20
2018-05-01 11:04