Wenn eine Zeile, die unmittelbar auf eine Übereinstimmung folgt, entfernt werden soll, muss Ihr sedProgramm 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 sedeine 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 sedprü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 . sedwird get 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 matches wird pgerintert.
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 matchmatch
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