Wenn eine Zeile, die unmittelbar auf eine Übereinstimmung folgt, entfernt werden soll, muss Ihr sed
Programm aufeinanderfolgende Übereinstimmungen berücksichtigen. Mit anderen Worten, wenn Sie eine Zeile nach einer Übereinstimmung entfernen, die auch übereinstimmt, sollten Sie wahrscheinlich auch die darauf folgende Zeile entfernen.
Es ist einfach genug implementiert - aber man muss ein wenig nachschauen.
printf %s\\n 0 match 2 match match \
5 6 match match match \
10 11 12 match 14 15 |
sed -ne'x;/match/!{g;//!p;}'
0
6
11
12
15
Dabei werden Halte- und Musterbereiche für jede eingelesene Zeile vertauscht, sodass die letzte Zeile jedes Mal mit der aktuellen verglichen werden kann. Wenn also sed
eine Zeile gelesen wird, tauscht sie den Inhalt ihrer Puffer aus - und die vorherige Zeile ist dann der Inhalt ihres Editierpuffers, während die aktuelle Zeile in den Hold-Space gestellt wird.
So sed
prüft die vorhergehende Zeile für ein Spiel zu match
, und wenn sie !
nicht die beiden Ausdrücke in der gefundene {
Funktion }
ausgeführt werden . sed
wird g
et der Halteraum , der durch den Musterraum überschrieben wird - was die aktuelle Zeile bedeutet , ist dann sowohl in den Griff und Musterräume - und dann wird es //
es für ein Spiel seiner zuletzt kompilierten regulären Ausdruck überprüfen - match
- und wenn es nicht match
es wird p
gerintert.
Dies bedeutet, dass eine Zeile nur gedruckt wird, wenn dies nicht der Fall ist, und die unmittelbar vorhergehende Zeile nicht . Sie verzichtet auch auf unnötige Auslagerungen für Sequenzen von es.match
match
match
Wenn Sie eine Version wünschen, die eine beliebige Anzahl von Zeilen löschen kann, die nach einem auftreten match
, wäre etwas mehr Arbeit erforderlich:
printf %s\\n 1 2 3 4 match \
match match 8 \
9 10 11 12 13 \
14 match match \
17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep
... ersetzen Sie die 5 durch die Anzahl der Zeilen (einschließlich der übereinstimmenden Zeile) , die Sie entfernen möchten ...
1
2
3
4
12
13
14
21