Löschen Sie n1 vorherige Zeilen und n2 Zeilen, die in Bezug auf eine Zeile mit einem Muster folgen

8
%Vor%

Ich muss ein bestimmtes Muster in einer Datei finden und gleichzeitig 5 Zeilen darüber und 4 Zeilen darunter löschen. Ich habe herausgefunden, dass die obige Zeile die Zeile mit dem Muster und vier Zeilen darunter entfernt.

%Vor%

Im sed-Handbuch wurde angegeben, dass ~ für die Linien steht, auf die das Muster folgt. Aber als ich es versuchte, waren es die Zeilen, die dem Muster folgten, die gelöscht wurden.

Also, wie lösche ich 5 Zeilen oberhalb und 4 Zeilen unterhalb einer Zeile, die das Muster gleichzeitig enthält?

    
Population Xplosive 25.02.2012, 08:57
quelle

5 Antworten

5

Eine Möglichkeit mit sed , vorausgesetzt, die Muster sind nicht nahe genug beieinander:

Inhalt von script.sed :

%Vor%

Lauf wie:

%Vor%     
Birei 25.02.2012, 11:48
quelle
2

Eine Lösung mit awk :

%Vor%

Aktualisierung:

Dies ist das Skript erklärt:

  • Ich erinnere mich an die letzten 5 Zeilen im Array lines mit rotatorischen Indizes (NR% 5; NR ist die Datensatznummer; in diesem Fall Zeilen).
  • Wenn ich das Muster in der aktuellen Zeile finde ( ~ ~ "XXXX ; awk ist der aktuelle Datensatz: in diesem Fall eine Zeile; awk ist der Erweiterte reguläre Ausdruck Vergleichsoperator) , Setze ich die Anzahl der gelesenen Zeilen zurück und beachte, dass ich 5 Zeilen löschen muss (einschließlich der aktuellen Zeile).
  • Wenn ich bereits 5 Zeilen gelesen habe, drucke ich die aktuelle Zeile.
  • Wenn ich keine zu löschenden Zeilen habe (was auch gilt, wenn ich 5 Zeilen gelesen habe, lege ich die aktuelle Zeile in den Puffer und inkrementiere die Anzahl der Zeilen. Beachten Sie, wie die Anzahl der Zeilen dekrementiert und dann erhöht wird, wenn Eine Zeile wird gedruckt.
  • Wenn Zeilen gelöscht werden müssen, drucke ich nichts und dekrementiere die Anzahl der zu löschenden Zeilen.
  • Am Ende des Skripts drucke ich alle Zeilen, die sich im Array befinden.

Meine ursprüngliche Version des Skripts war die folgende, aber ich habe es am Ende auf die obige Version optimiert:

%Vor%

sed ist ein großartiges Werkzeug! Ich empfehle dringend, dass Sie ein Tutorial im Netz finden und es lesen. Eine wichtige Sache: %code% arbeitet mit Erweiterte reguläre Ausdrücke ( ERE ). Ihre Syntax unterscheidet sich ein wenig von Regulärer Standardausdruck ( RE ), die in %code% verwendet wird, aber alles, was mit RE getan werden kann, kann mit ERE erledigt werden.

    
jfg956 25.02.2012 11:53
quelle
1

Die Idee ist, 5 Zeilen zu lesen, ohne sie zu drucken. Wenn Sie das Muster finden, löschen Sie die unbedruckten Linien und die 4 Linien unten. Wenn Sie das Muster nicht finden, merken Sie sich die aktuelle Zeile und drucken Sie die erste unbedruckte Zeile. Am Ende drucken Sie was unbedruckt ist.

%Vor%

Das funktioniert natürlich nur, wenn Sie ein Muster in der Datei haben. Wenn Sie viele haben, müssen Sie 5 neue Zeilen nach dem Finden Ihres Musters lesen, und es wird kompliziert, wenn Sie Ihr Muster wieder in diesen Zeilen haben. In diesem Fall denke ich, sed ist nicht das richtige Werkzeug.

    
jfg956 25.02.2012 11:03
quelle
1

Dies könnte für Sie funktionieren:

%Vor%

oder das:

%Vor%

eine effizientere Sed-Lösung:

%Vor%     
potong 25.02.2012 11:50
quelle
1

Wenn Sie das Ergebnis lieber in eine Datei als in stdout ausgeben möchten, kann vim dies sehr effizient tun:

%Vor%

oder

%Vor%

um die Datei direkt zu bearbeiten.

    
Robbie Clarken 13.09.2013 02:59
quelle

Tags und Links