Löschen Sie Zeilen mit passendem Muster nach der ersten Zeile mit sed

Löschen Sie Zeilen mit passendem Muster nach der ersten Zeile mit sed

Ich möchte jede Zeile löschen, die ein Muster nach der ersten Zeile enthält (das Muster ist /^country\t/). Ich kann löschenjedenVorkommen mit sed '/^country\t/d' in.txt > out.txt, aber ich möchte das erste Vorkommen in der ersten Zeile behalten.

Die Hintergrundgeschichte ist, dass ich ein Verzeichnis mit tabulatorgetrennten Dateien mit Headern habe und diese Dateien mit verkette cat. Ich möchte die zusätzlichen Header entfernen.

In Vim könnte ich so etwas tun wie : 2,$g/^country\t/d, aber ich komme nicht auf die sed-Lösung. Beim Versuch sed '2,$ /^country\t/d in.txt > out.txterhalte ich den Fehler unknown command: /.

Danke!

Antwort1

Es gibt keinen direkten Weg, aber dies ist ein Workaround:

sed -e '1,2 s/^country\t/NOCHANGE/' -e '/^country\t/d' -e 's/NOCHANGE/country/'  in.txt > out.txt

Antwort2

Das könnte für Sie funktionieren:

sed '1b;/^country\t/d' in.txt > out.txt

oder

sed '1!{/^country\t/d}' in.txt > out.txt

Antwort3

sed '/pattern/{x;/pattern/!{x;h;b;};x;d}' file

Dadurch werden alle übereinstimmenden Zeilen NACH der ersten übereinstimmenden Zeile gelöscht. Kommentar:

/Muster/- Muster abgleichen

{X- wenn das oben genannte übereinstimmt, Muster austauschen und Puffer halten

;/Muster/!{x;h;b;}- Testen Sie nun den Musterpuffer (beim ERSTEN Treffer ist er nun leer). Wenn dies nicht der Fall ist, tauschen Sie mit „x“ das Muster und den Haltepuffer wieder aus, kopieren Sie dann den Musterpuffer in den Haltepuffer „h“, verzweigen Sie mit „b“ zum Ende des Skripts und laden Sie die nächste Zeile.

;x;d}- dieses Bit wird nur ausgeführt, wenn die negierte Musterübereinstimmung im vorherigen Schritt fehlschlägt - d. h. der Musterpuffer stimmt mit Ihrem Muster überein. In diesem Fall tauschen Sie den Hold- und den Musterpuffer wieder aus, 'x', und löschen die Zeile 'd'.

Antwort4

Wenn das /Muster/ nicht mit einer leeren Zeile übereinstimmt, verwenden Sie „das holdLeerzeichen wird als leere Zeile initialisiert“, um die erste Übereinstimmung zu testen:

Behalten Sie die erste Zeile bei:

sed '/pattern/ {x; /^$/!d; g;}' file

Lassen Sie die erste Zeile weg:

sed '/pattern/ x' file

Bearbeiten Sie nur die erste Zeile:

sed '/pattern/ {x; /^$/!b'$'\n'' g; s/pattern/xx/; }' file

editieren Sie einfach folgende Zeile:

sed '/pattern/ {x; s/pattern/xx/; t'$'\n'' g; }' file

PS: Auf oder folgt $'\n'(kein ;) , was bsd sed freut.tb

verwandte Informationen