
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
awk
kö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 awk
oder dieGnu Awk-BenutzerhandbuchfürWegMehr Details.
Antwort4
grep -A 1 "test$" in.txt | grep -B 1 "test2$"
Im Grep-Handbuch
-A NUM
Drucken Sie NUM Zeilen des nachfolgenden Kontexts nach den übereinstimmenden Zeilen.
-B NUM
Drucken Sie NUM Zeilen des führenden Kontexts vor den übereinstimmenden Zeilen.
Der Befehl grep -Pzo ".*test$\n.*test2$" in.txt
funktioniert auch, aber im Handbuch steht „Dies ist höchst experimentell und grep -P könnte vor nicht implementierten Funktionen warnen.“