2016-04-28 12 views
2

Ich habe eine sehr große Textdatei (40GB gziped) wo Datenblöcke durch // getrennt sind.Wählen Sie den ganzen Textblock, der durch einige Zeichen begrenzt wird

Wie kann ich Datenblöcke auswählen, bei denen eine bestimmte Zeile einem bestimmten Kriterium entspricht? Das heißt, kann ich ein Muster und erweitere die Auswahl in beiden Richtungen auf das // Delimiter? Ich kann keine Vermutungen über die Größe des Blocks und die Position der Linie machen.

not interesting 1 
not interesting 2 
// 
get the whole block 1 
MATCH THIS LINE 
get the whole block 2 
get the whole block 3 
// 
not interesting 1 
not interesting 2 
// 

Ich möchte den Datenblock mit MATCH THIS LINE wählen:

get the whole block 1 
MATCH THIS LINE 
get the whole block 2 
get the whole block 3 

ich sed versucht, aber kann meinen Kopf nicht um die Musterdefinition zu erhalten.

sed -n -e '/\/\//,/MATCH THIS LINE/ p' file.txt 

aber es funktioniert nicht die // passend: Dies sollte zum Beispiel //-MATCH THIS LINE entsprechen.

Ist es möglich, dies mit GNU-Kommandozeilen-Tools zu erreichen?

Antwort

5

Mit GNU awk (durch Multi-char RS), können Sie den Datensatz-Trenn auf // gesetzt, so dass jeder Datensatz einen // separierten Satz von Zeichen ist:

 
$ awk -v RS="//" '/MATCH THIS LINE/' file 

get the whole block 1 
MATCH THIS LINE 
get the whole block 2 
get the whole block 3 

Hinweis dies läßt eine leere Zeile oben und unten, weil es die neue Zeile unmittelbar nach // fängt und wieder ausdruckt, sowie die letzte vor dem // am Ende. Um sie zu entfernen, können Sie eine Pipeline an awk 'NF'.

Um das Trennzeichen zwischen Datenblöcke drucken Sie (dank 123) sagen kann:

awk -v RS="//" '/MATCH THIS LINE/{print RT $0 RT}' file 
+0

Perfect, das funktioniert. Ist es möglich, das '//' zu behalten und es auf die Ausgabe zurück zu drucken? –

+0

@MartinPreusse wie genau? Über und unter dem Block? – fedorqui

+0

Unten. I.e. Behalte das Trennzeichen zwischen Datenblöcken. –

Verwandte Themen