drucken Sie eine unterschiedliche Anzahl von Zeilen vor und nach einem Muster

1

Ich habe ein Verzeichnis mit Tausenden von Dateien mit folgenden sich wiederholenden Mustern, die Hunderte von Abschnitten enthalten -

###############
# Section 1
###############
some text
more text
some more text
some text
more text
some more text    
###############
# Section 2
###############
some text
more text
some more text
interesting-pattern
some text
more text
some more text    
###############
# Section 3
###############
some text
more text
some more text
some text
more text
some more text

Was ich tun muss, ist, einen Weg zu finden, um den gesamten ABSCHNITT zu extrahieren, in dem das "interessante Muster" existiert.

Ich habe versucht, ein grep -iEr 'interesting-pattern' mit den Flags -A und -B zu erstellen, aber das funktioniert nicht, da in jeder Datei vor und nach dem Intersting-Pattern eine unterschiedliche Anzahl von Zeilen im Abschnitt vorhanden sein kann.

Wie geht das am besten?

user168115
quelle

Antworten:

0

Dies ist kein Job für grep, sondern für ein besseres Tool wie awk.

Die einfache Problemumgehung besteht darin, gnu awk mit einem benutzerdefinierten Datensatztrennzeichen wie RS zu verwenden Section.

Verwenden des Wortes "Section" zum Trennen von Zeilen, unabhängig davon, was sich zwischen den Wörtern befindet, Section 1und Section 2wird als eine Zeile für awk betrachtet.
Gleiches gilt für Abschnitt 2 - Abschnitt 3 usw.

Jetzt müssen Sie nur noch die richtige "Zeile" = die "Zeile" ausgeben, die die enthält interesting-pattern.

$ awk -v RS="# Section " '/interesting-pattern/{print RT $0}' file1
# Section 2
###############
some text
more text
some more text
interesting-pattern
some text
more text
some more text    
###############

Da Gnu Awk Regex in RS (Record Separator) akzeptieren kann, können Sie in RS auch etwas Komplizierteres anwenden:

$ awk -v RS="###############\n# Section " '/interesting-pattern/{print RT $0}'
###############
# Section 2
###############
some text
more text
some more text
interesting-pattern
some text
more text
some more text    

PS: {print RTWeist awk an, den aktuell verwendeten Record Separator zu drucken

George Vasiliou
quelle
1
Danke George! Ich habe Ihren Befehl verwendet und ein paar Änderungen daran vorgenommen, um rekursive Such- und Druckdateinamen hinzuzufügen - für Datei in find ~/your-directory-path/ -type f; do awk -v RS = "############## \ n #" '/ interesting-pattern / {print FILENAME "\ n", RT $ 0}' $ file; getan . Dies durchsucht rekursiv alle Dateien in "~ / your-directory-path", druckt den Dateinamen, bevor eine Übereinstimmung gefunden wird, druckt eine neue Zeile nach dem Dateinamen und druckt dann den übereinstimmenden Abschnitt.
user168115