Kann ich mit sed nur die erste passende Zeile löschen?

Kann ich mit sed nur die erste passende Zeile löschen?

Ich habe eine Datei testfile.txtmit

pippo=x
pluto=y
1234=z

Ich möchte nur löschender ersteZeilenübereinstimmung /^[a-z]\+=/(in diesem Beispiel die erste Zeile).

Ich habe es mit dem folgenden Befehl versucht, jedoch ohne Erfolg:

sed   '/^[a-z]\+=/,+0d' testfile.txt

aber der erstezweiZeilen werden gelöscht.

Gibt es eine Möglichkeit, diese Aufgabe mit zu erledigen sed?

Grüße

Antwort1

Das Problem mit Ihrem sedBefehl

$ sed '/^[a-z]\+=/,+0d' testfile.txt

ist, dass das sedSkript angewendet wird aufjedenZeile der Eingabedaten.

Das +0(eine GNU-Erweiterung) bedeutet, dass Ihr Skript äquivalent ist zu

$ sed '/^[a-z]\+=/d' testfile.txt

und die erste und zweite Zeile würden gelöscht, wie Sie bemerkt haben.

Übrigens erhalten Sie genau das gleicheWirkungmit +1, aber aus anderen Gründen. Der dBefehl würde nicht einzeln auf Zeile eins und zwei angewendet, sondern auf die ersten beiden Zeilen, da die erste Zeile eine Übereinstimmung aufweist (d. h. der Bereich des dBefehls würde Zeile eins und eine weitere Zeile umfassen, +1). Dadurch wird Zeile drei nicht gelöscht, da sie außerhalb des Bereichs liegt.

Die GNU- sedLösung

$ sed '0,/^[a-z]\+=/{//d}' testfile.txt

das vom Benutzer @Whitefield gepostete funktioniert und ist ziemlich gut (obwohl die -rOption unnötig ist und die 0Startadresse 1in diesem Fall geändert werden kann, wenn Sie mehr POSIX-artig sein möchten).

Eine BSD- sedVariante des gleichen Ansatzes würde so aussehen

$ sed '1,/^[a-z]+=/{/^[a-z]+=/d
  }' testfile.txt

Das Escapen +ist nur notwendig, wenn Ihr sedSystem „veraltete grundlegende reguläre Ausdrücke“ statt „moderne grundlegende reguläre Ausdrücke“ implementiert. Sowohl BSD sedals auch GNU sedauf meinem System (Mac OS X) scheinen vom „modernen“ Typ zu sein. POSIX kennt diese Unterscheidung nicht, und wenn ich die Handbücher ( re_format(7)auf BSD, wo diese Unterscheidung gemacht wird) und die POSIX-Spezifikation nebeneinander lese, wird mir schwindelig.

Antwort2

@John1024 Es tut mir leid, aber Ihre Lösung funktioniert nur, wenn die erste übereinstimmende Zeile die erste Zeile der Datei ist.

Ich habe das Problem mit dem folgenden Code gelöst sed -r '0,/^[a-z]\+=/{//d;}' testfile.txt, bin aber immer noch davon überzeugt, dass meine vorherige Lösung auch mit POSIX-Sed hätte funktionieren müssen.

Tatsächlich bestand die Idee darin, als zweite Zeilenadresse einen Offset von 0 Zeilen anzugeben … aber dadurch wird trotzdem auch die folgende Zeile gelöscht, was nach einem Fehler klingt.

von man sedin Ubuntu 14.04

… addr1,+N. Stimmt mit addr1 und den N Zeilen nach addr1 überein. …

verwandte Informationen