Gibt es eine Möglichkeit, grep
ein Protokoll zu erstellen und Text zwischen den Protokolleintragstrennzeichen zu finden? Unsere Protokolldatei trennt die Zeileneinträge mit den Zeichen " -------
". Wenn ich also nach dem Textwort suche, möchte ich alle Zeilen vor und nach den Trennzeichen im Protokoll.
Beispielprotokoll
------------------------------------------------------------------------
r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines
Removed unused "Calculated Fields" column entry.
Jira ID: JIRA-977
------------------------------------------------------------------------
Im obigen Beispiel würde ich das Wort „Fields“ mit Grep durchsuchen, möchte aber alle Zeilen zwischen den „ ----
“-Zeilen
Antwort1
Wenn Sie wissen, wie groß der Datensatz ist, können Sie zusätzliche Kontextzeilen vor ( -B
) und nach ( -A
) der übereinstimmenden Zeile ausgeben, z. B.
grep -A2 -B2 'Fields' sample.log
oder für den Kontext sowohl vor als auch nach der Übereinstimmungszeile
grep -C3 'Fields' sample.log
Soweit ich weiß, besteht die einzige Möglichkeit, in GNU grep eine echte mehrzeilige Übereinstimmung (anstatt einer einzelnen Zeile plus Kontext) zu erzielen, darin, den PCRE-Regex-Modus ( -P
) mit dem -z
Flag zu verwenden, um Zeilenumbrüche zu verhindern. Sie könnten beispielsweise versuchen
grep -zPo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'
Dies führt eine nicht gierige Übereinstimmung der Zeichenfolge durch, Fields
die von beliebigen Zeichen ODER Zeilenumbrüchen umgeben ist, vorausgesetzt, sie wird von demZeilenumbruch-Bindestriche-ZeilenumbruchTrennzeichen. Ein äquivalenter Ausdruck in pcregrep ist
pcregrep -Mo '(\n-+\n)\K(.|\n)+?Fields(.|\n)+?(?=\n-+\n)'
Eine weitere Option für diese Art von datensatzstrukturierten Daten ist awk: Insbesondere ermöglicht GNU awk die Verwendung eines regulären Ausdrucks für die interneDatensatztrennzeichenRS zB
$ gawk -vRS='\n-+\n' '/Fields/ {print}' sample.log
r132279 | USERID | 2014-04-30 12:59:09 -0700 (Wed, 30 Apr 2014) | 3 lines
Removed unused "Calculated Fields" column entry.
Jira ID: JIRA-977
Antwort2
Eine Perl-Lösung ähnlich der gawk
inAntwort von steeldriverfalls gawk
nicht verfügbar:
perl -ne 'BEGIN{$/= "-"x72 . "\n"} chomp and print if /Fields/' log_file
Ersetzen Sie 72 durch die tatsächliche Anzahl der Bindestriche in Ihrem Trennzeichen.