Ich habe eine riesige Protokolldatei und möchte das erste Auftreten eines Musters erfassen und direkt nach diesem Auftreten ein anderes Muster finden .
Zum Beispiel:
123
XXY
214
ABC
182
558
ABC
856
ABC
In meinem Beispiel möchte ich 182
das nächste Vorkommen von finden und dann findenABC
Das erste Vorkommen ist einfach:
grep -n -m1 "182" /var/log/file
Dies gibt aus:
5:182
Wie finde ich das nächste Auftreten von ABC?
Meine Idee war es grep
, die ersten n
Zeilen (im obigen Beispiel n=5
) zu überspringen , basierend auf der Zeilennummer 182. Aber wie mache ich das?
grep
die verwendet wird? Ich denke nicht, dass dies möglich ist,grep
aber es wäre einfach mitawk
odersed
(allein oder in Kombination mitgrep
).grep
ist nicht erforderlich. Ich bin noch nicht so vertraut mitsed
oderawk
. Wenn Sie eine gute Lösung haben, lassen Sie es mich hören! :) @don_crissti nur die erste Zeile sollte gedruckt werden. Die anderen Vorkommnisse sind mir egal.Antworten:
Mit können
sed
Sie eine Range- undq
UIT-Eingabe an einem einzigen Abschluss verwenden:Ebenso können Sie mit GNU
grep
die Eingabe auf zweigrep
s aufteilen :... was druckt ...
... um anzuzeigen , dass die erste
grep
gefunden hat, dass ein-F
Literal mit festen Zeichenfolgen, die-x
gesamte Zeile 182 , 5 Zeilen vom Beginn des Lesens an übereinstimmt, und die zweite eine ähnlich typisierte ABC- Übereinstimmung 2 Zeilen vom Beginn des Lesens gefunden hat - oder 2 Zeilen nach dem erstengrep
Abbruch in Zeile 5.Von
man grep
:Ich habe ein Dokument hier verwendet, um eine reproduzierbare Demonstration zu ermöglichen, aber Sie sollten wahrscheinlich Folgendes tun:
Es funktioniert auch mit anderen Shell-Verbundbefehlskonstrukten wie:
quelle
grep
's anstelle eines;
... no-gogrep
gemeinsam nutzen, ist praktisch eine Pipeline für sie. Noch etwas: Ich habe es versucht, ohne die Markierungslinie zu drucken, aber es istsed '//,/^ABC$/!d;/^ABC$/!d;q'
ein seltsamer Fehler aufgetreten. Was macht//
dassed
Ding ansehen - habe es einfach ganz schnell ausgeschrieben.sed
Ding funktioniert also - du hast die Referenz einfach weggelassen . In könnensed
Sie/address/
mit einer leeren//
Adresse wieder auf den letzten verweisen . Also/^182$/command;//,/next_address/
einfach/^182$/command;/^182$/,/next_address/
. Ihr Fehler war wahrscheinlich kein vorheriger regulärer Ausdruck, wenn Sie eine GNU verwendetensed
. Das Pipe-Lseek-Ding kann übrigens durch Indirektion über die/dev/fd/[num]
Links auf Linux-Systemen manipuliert werden - aber wenn Sie nicht sehr vorsichtig sind, mit Puffern gut umzugehen (wie beidd
) , ist das normalerweise ein verlorener Kampf.Verwendung
grep
mit Perl-kompatiblen regulären Ausdrücken (pcregrep
):Mit dieser Option kann
-M
das Muster mit mehr als einer Zeile\K
übereinstimmen und enthält kein übereinstimmendes Muster (bis zu diesem Punkt) in der Ausgabe. Sie können entfernen,\K
wenn Sie die gesamte Region als Ergebnis haben möchten.quelle
quelle
awk '/^182$/{z=1;next} z&&/^ABC$/{print NR":"$0;exit}' file
- oder Sie können mindestens eine explizitegetline()
Schleife schreiben, die normalerweise ungeschickter ist, oder mit einem Bereich, der fast wie @ JRFergusons Perl ist, klug (?) sein:awk '!x&&/^182$/,/^ABC$/ {x=NR":"$0} END{print x}
Eine Perl-Variante, die Sie verwenden können, ist:
... die Linien im passenden Bereich druckt.
Wenn Ihre Datei mehr als einen übereinstimmenden Bereich enthielt, können Sie die Ausgabe nur auf den ersten Bereich beschränken, indem Sie das
/
Trennzeichen auf ändern?
quelle
Bleib bei Just
grep
und fügetail
& hinzucut
, du könntest ...grep für die Zeilennummer der ersten Übereinstimmung von
182
:Verwenden , die für die ganze grep
ABC
ist erst nach der ersten passenden Zeile oberhalb, unter Verwendung vontail
s-n +K
zur Ausgabe nach der K - ten Zeile. Alle zusammen:Oder fügen Sie
-m 1
erneut hinzu, um nur die erste Übereinstimmung zu findenABC
Verweise:
man
Seiten/programming/6958841/use-grep-to-report-back-only-line-numbers
quelle
Eine andere Variante ist diese:
Die Flagge -An greift nach dem Spiel n Zeilen und 99999 soll nur sichergehen, dass wir nichts verpassen. Größere Dateien sollten mehr Zeilen haben (überprüfen Sie mit "wc -l").
quelle
Der Bereichsoperator
,
kann hier verwendet werden:Der Bereichsoperator kann
..
zusammen mit dem Nur-einmal-Match-Operatorm??
hier in verwendet werdenPerl
quelle