2017-12-17 10 views
2

Wie kann sed verwendet werden, um eine \n an den Anfang und an das Ende jeder Zeile mit dem Muster %%###? Dies ist, wie weit ich bekam:Wie füge ich am Anfang und Ende jeder Zeile eine neue Zeile hinzu, die einem Muster entspricht?

Wenn foo.txt enthält

foobar 
%%## Foo 
%%### Bar 
foobar 

dann sed 's/^%%###/\n&\n/g' foo.txt

foobar 
%%## Foo 

%%### 
Bar 
foobar 

statt

foobar 
%%## Foo 

%%### Bar 

foobar 

Hinweis gibt: Das zu this post Zusammenhang scheint

Update: Ich bin tatsächlich auf der Suche nach Fall, wo die Zeilen beginnend mit mit dem Muster nur berücksichtigt werden.

Antwort

1

Mit GNU sed:

sed 's/.*%%###.*/\n&\n/' file 

Ausgang:

 
foobar 
%%## Foo 

%%### Bar 

foobar 

&: auf den Teil des Musterbereichs Siehe die

abgestimmt Wenn Sie Ihre bearbeiten möchten Datei "an Ort und Stelle" verwenden Sie seds Option -i.

+0

Hallo, danke. Hast du eine Version, die nur Linien * beginnend * mit dem Muster übereinstimmt? –

+0

Ersetzen Sie zuerst '. *' Durch '^'. – Cyrus

+0

ah, danke (mein Test war also korrekt). Vielen Dank! –

1

Es ist mühsam, Zeilenumbrüche direkt über sed hinzuzufügen. Aber hier ist eine Option, wenn Sie perl zur Verfügung haben:

$ foo.txt | perl -pe 's/(.*%%###.*)/\n$1\n/' 

Hier erfassen wir jede passende Zeile, die wie jede Linie definiert ist, enthält das Muster %%### überall, und dann mit ersetzen wir diese Linie umgeben von Vorder- und Hinterzeilenumbrüche .

+0

Wie ist das weniger umständlich als [die Sed-Lösung] (https://Stackoverflow.com/a/47853333/1745001)? –

+0

@EdMorton Ich habe an einigen Stellen gelesen, dass das Generieren von Zeilenumbrüchen von SED Vorbehalte hatte. Diese Antwort schien vernünftig. –

+0

Der einzige Vorbehalt ist, dass einige seds '\ n' nicht als Zeilenumbruch akzeptieren und Sie einen umgekehrten Schrägstrich benötigen, gefolgt von einem buchstabengetreuen Newline-Zeichen oder wenn Sie sich auf die Shell verlassen, um '$' \ n'' zu erweitern oder kann perl installieren, dann hast du eine sed, die '\ n' akzeptiert. –

1

Dies könnte für Sie arbeiten (GNU sed):

sed '/%%###/!b;G;i\\' file 

Für jene Linien, die die Kriterien erfüllen, eine neue Zeile aus dem Laderaum hängen (der Halteraum standardmäßig eine neue Zeile enthält) und eine leere einfügen Linie.

Ein anderer Weg:

sed -e '/%%###/!b;i\\' -e 'a\\' file 

Dieses Mal einfügen und dann leere Zeilen anhängen.

N.B. Auf die i und a muss eine neue Zeile folgen. Dies kann erreicht werden, indem sie in separate Aufrufe eingefügt werden: -e.

Ein dritte Weg:

sed '/%%###/!b;G;s/.*\(.\)/\1&/' file 

Wie in der ersten Art und Weise, eine neue Zeile aus dem Laderaum angehängt, kopieren dann d.h.das letzte Zeichen der geänderten aktuellen Zeile und es der aktuellen Zeile voranstellen.

Noch eine andere Art und Weise:

sed '/%%###/{x;p;x;G}' file 

Swap in den Halteraum, drucken Sie das Newline, tauschen zurück und das Newline anhängen.

N.B. Wenn der Halteraum kann nicht leer sein (ein vorhergehender, x, h, H, g oder G Befehl geändert Es kann) der Puffer gelöscht werden kann, bevor es gedruckt wird (p), indem den Befehl zap z verwenden.

Und natürlich:

sed '/%%###/s/^\|$/\n/g' file 
0

persönlich einen String Ich würde statt regexp Vergleich verwenden, da im Text keine repexp Zeichen gibt es Sie passen wollen und wenn es Ihnen nicht als behandelt würden waren wollen so, und nur Druckzeilenumbrüche um die Zeichenfolge stattdessen die Zeichenfolge modifizieren selbst:

awk '{print ($1=="^%%###" ? ORS $0 ORS : $0)}' file 

die oben wird in jeder Schale auf jedem UNIX-Box mit jedem awk arbeiten und leicht modifiziert, wenn Sie mehrere Leerzeilen nicht wollen, zwischen aufeinander folgenden %%### li oder wollen keine Leerzeilen hinzugefügt werden, wenn die vorhandenen umgebenden Zeilen bereits leer sind oder Sie etwas anderes tun müssen.

Verwandte Themen