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

2

Ich möchte jede Zeile löschen, die ein Muster nach der ersten Zeile enthält (das Muster ist /^country\t/ ). Ich kann löschen jeden Vorkommen 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 tabulatorgetrennter Dateien mit Headern habe und diese Dateien mit verkette cat. Ich möchte die zusätzlichen Header entfernen.

In Vim könnte ich sowas machen : 2,$g/^country\t/d, aber ich kann die sed-Lösung nicht herausfinden. Wenn ich es versuche sed '2,$ /^country\t/d in.txt > out.txt Ich bekomme den Fehler unknown command: /.

Vielen Dank!

Richard Herron
quelle

Antworten:

1

Es gibt keinen direkten Weg, aber dies ist eine Problemumgehung:

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

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
potong
quelle
0
sed 's/[^country]*//2' <old >new

Dies sollte alle Instanzen des Landes mit Ausnahme der ersten ändern (wenn Sie zwei in der ersten Zeile haben, wird nur die erste beibehalten).

Bruno9779
quelle
Danke, aber ich möchte die ganze Zeile löschen. Ist meine einzige Wahl mit dem s///g konstruiere und mache das muster so ähnlich wie /^country.*\n/?
Richard Herron
1
Überprüfen Sie dies heraus: grymoire.com/Unix/Sed.html
Bruno9779
+1, guter Link! (Ich hatte das bei meinen Suchen gefunden, konnte aber @ johnshen64s Hack nicht zusammenfügen.)
Richard Herron
0
sed '/pattern/{x;/pattern/!{x;h;b;};x;d}' file

Dadurch wird jede übereinstimmende Zeile NACH der ersten übereinstimmenden Zeile gelöscht. Kommentar:

/Muster/ - Muster anpassen

{x - Wenn das obige übereinstimmt, tauschen Sie das Muster aus und halten Sie den Puffer

; / pattern /! {x; h; b;} - Testen Sie jetzt den Musterpuffer (es wird jetzt sein   leer beim ERSTEN Treffer) und wenn nicht! bereits enthalten Muster   Vertausche dann das Muster 'x' und halte den Puffer wieder zurück, dann kopiere das   Musterpuffer in den Haltepuffer 'h' und Verzweigung 'b' zum Ende von   das Skript und laden Sie die nächste Zeile.

; x; d} - Dieses Bit wird nur ausgeführt, wenn das negierte Muster übereinstimmt   Der vorherige Schritt schlägt fehl, d. h. der Musterpuffer stimmt mit Ihrem überein   Muster. Tauschen Sie in diesem Fall den Hold- und Pattern-Buffer erneut aus   'x' und 'd' die Zeile löschen.

Santrix
quelle
0

Wenn das / pattern / nicht mit einer leeren Zeile übereinstimmt, verwenden Sie "the hold Leerzeichen wird als Leerzeile initialisiert ", um die erste Übereinstimmung zu testen:

Behalte die erste Zeile bei:

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

Lass die erste Zeile fallen:

sed '/pattern/ x' file

bearbeite nur die erste Zeile:

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

Bearbeiten Sie nur die folgende Zeile:

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

PS: $'\n' (kein ; ) folgt t oder bund bsd sed glücklich machen.

James Z.M. Gao
quelle