Grep nach Text-/Zeilenblock

Grep nach Text-/Zeilenblock

Ich habe einen Text, der aus mehreren Zeilen besteht. Ich muss also mehrere Zeilen mit GREP durchsuchen. Ich habe beispielsweise einen sich wiederholenden Text und sollte mit GREP die Zeilen finden, die diese sich wiederholenden Schlüsselwörter enthalten.

grep -o "test|test2" textfile

Mein Text:

123|never for your|test
123421|never for your|test2
123412|never for your|test3
12341|never for your|test4
12311|never for your|test2
123312312|never for your|test
123321312|never for your|test2

Ich sollte:

123|never for your|test
123421|never for your|test2
123312312|never for your|test
123321312|never for your|test2

Es funktioniert, aber nicht so, wie ich es möchte. Es sucht im Text nach allen Wörtern „Test“ und „Test2“. Aber ich möchte Textblöcke erhalten, wie ein Muster, bei dem nach „Test“ nur „Test2“ kommt. Haben Sie Ideen?

Antwort1

Kurzes Shell-Skript mit sed. Erstellt eine Liste mit Zeilennummern für den zweiten Fall und vergleicht sie mit den Zeilennummern für den ersten Fall. Druckt übereinstimmende Paare. Verwendet das erste Argument als Dateinamen. Könnte leicht erweitert werden, um das zweite und dritte Argument als zu vergleichende Muster zu verwenden. Könnte als findnext.sh gespeichert und ausgeführt werden:

$ sh findnext.sh testfile

Sollte schnell gehen, da die Datei nur in zwei Schritten durchsucht werden muss, und hat den Vorteil, dass es vollständig portierbar ist.

#!/bin/sh 
# Line numbers matching test1
mt2=$(sed -ne '/test1/=' < $1 | tr '\n' '/')

for l in $(sed -ne '/test/=' < $1); do
    nextline=$(expr $l + 1)
    [ "${mt2#*$nextline/}" != "$mt2" ] && sed -ne $l,${nextline}p <$1
done

Antwort2

Sie können grep -E oder egrep ausprobieren. Bitte versuchen Sie es so

#this will show lines that have test or test2
    grep -E "test|test2" file

Wenn Sie eine Zeile mit Test und Test2 wie diese anzeigen möchten: test|test2, tun Sie dies

# This will show lines that has test|test2
    grep "test\|test2" file

Antwort3

awkkönnte hierfür Ihr Werkzeug sein:

awk '/test$/, /test2$/' < block-text-lines.txt 

die allgemeine Form ist:

awk '/start-pattern/, /end-pattern/{command}'

Da der Befehlsblock standardmäßig auf Drucken eingestellt ist, reichen die Start- und Endmuster aus.

Schauen Sie sich an man awkoder dieGnu Awk-BenutzerhandbuchfürWegMehr Details.

Antwort4

grep -A 1 "test$" in.txt | grep -B 1 "test2$"

Im Grep-Handbuch

-A NUMDrucken Sie NUM Zeilen des nachfolgenden Kontexts nach den übereinstimmenden Zeilen.

-B NUMDrucken Sie NUM Zeilen des führenden Kontexts vor den übereinstimmenden Zeilen.

Der Befehl grep -Pzo ".*test$\n.*test2$" in.txtfunktioniert auch, aber im Handbuch steht „Dies ist höchst experimentell und grep -P könnte vor nicht implementierten Funktionen warnen.“

verwandte Informationen