Wie filtere ich 2 Zeilen für jede Zeile, die zum regulären Ausdruck grep passt?
Das ist mein minimaler Test:
SomeTestAAAA
EndTest
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestAABC
EndTest
SomeTestACDF
EndTest
Und natürlich habe ich zB probiert grep -vA 1 SomeTestAA
was nicht geht.
gewünschte Ausgabe ist:
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest
text-processing
grep
Behrooz
quelle
quelle
Antworten:
Sie können
grep
mit-P
(PCRE) verwenden:(?!AA)
ist die Null gewährleistet negative Vorgriffs - Musterbreite , dass es keineAA
nachSomeTest
.Prüfung :
quelle
\.
sogrep -P -A 1 'SomeTest\.(?!AA)' file.txt
odergrep -P -A 1 'SomeTest(?!\.AA)' file.txt
SomeTest*\nEndTest
vorliegen, sodass Sie tatsächlichgrep
alle übereinstimmenden Zeilen anpingen,SomeTest*
jedoch nichtSomeTestAA
+ eine Kontextzeile nach der Übereinstimmung. Fügen Sie der Eingabe weitere Zeilen hinzu (z. B. fügen Siefoobar
nach jederEndTest
Zeile eine Zeile hinzu), und wiederholen Sie den Vorgang.Hier ist eine
sed
Lösung (-n
ohne automatisches Drucken), die mit beliebigen Eingaben funktioniert:also mit einem eingang wie
Laufen
Ausgänge
Das heißt, es werden genau die Zeilen entfernt,
grep -A1 SomeTestAA infile
die ausgewählt würden:quelle
//
passt/SomeTestAA/
. Ich dachte, in diesem Fall würde es den negierten Ausdruck abgestimmt hat:/SomeTestAA/!
. (+1)!
ist nicht Teil des RE , es ist einesed
Sache.Vielleicht haben Sie mehr Glück mit etwas, das mehrzeilige Regionen als einzelne Datensätze betrachtet. Es gibt eine,
sgrep
die ich nicht viel benutzt habe.Es gibt auch awk, wo Sie das Trennzeichen für die Eingabe und die Ausgabe von Datensätzen nach Belieben einstellen können.
Der größte Teil des awk-Programms steht in einfachen Anführungszeichen, aber am Ende werden doppelte Anführungszeichen verwendet, damit die
$pat
Shell-Variable erweitert werden kann.quelle
awk -vpat="^SomeTestAA" -vRS="\nEndTest\n" 'BEGIN{ ORS=RS } $0 !~ pat' file
Eine Möglichkeit ist die Verwendung
p
erlc
kompatiblerr
egularere
Ausdrückegrep
:Mit dieser Option
-M
kann das Muster mit mehr als einer Zeile übereinstimmen.quelle
grep
PCRE (über die-P
Option ) bereits unterstützt , was ist der Vorteil der Verwendungpcregrep
?grep
unterstützt keine-M
Option.Mit standard
sed
:Das
sed
Skript analysiert die Eingabedatei Zeile für Zeile, und wenn eine Linie des Muster übereinstimmtSomeTestAA
, die beidensed
BearbeitungsbefehleN
undd
ausgeführt werden. DerN
Befehl hängt die nächste Eingabezeile an den Musterbereich (den Puffer, dersed
bearbeitet werden kann) an,d
löscht den Musterbereich und startet den nächsten Zyklus.quelle
Sie können den Befehl von GNU verwenden
sed
,d
um eine Zeile zu löschen und mit einem Präfix zu versehen/pat/,+N
, um Zeilen auszuwählen, die dem Muster und den folgenden N Zeilen entsprechen. In Ihrem Fall ist N = 1, da Sie nur die einzelne nachfolgende Zeile nach einer übereinstimmenden Zeile löschen möchten:quelle
Versucht mit Below sed Befehl und es hat gut funktioniert
Befehl
Ausgabe
quelle