Wie kann ich ein Verzeichnis nach Zeilen durchsuchen , die "Foo" enthalten, aber nur Übereinstimmungen erhalten, wenn die nächste Zeile auch "Bar" enthält?
grep
regular-expression
Nathan Long
quelle
quelle
Antworten:
@ warl0ck zeigte mir die richtige Richtung mit
pcregrep
, aber ich sagte "enthält", nicht "ist", und ich fragte nach einem Verzeichnis, nicht nach einer Datei.Das scheint bei mir zu funktionieren.
quelle
Grep selbst scheint es nicht zu unterstützen, verwenden Sie stattdessen pcregrep:
pcregrep -M "Foo\nBar" file
Bekam:
quelle
Foo
undBar
würde die gesamte Linie umfassen.Mit einem
sed
Skript:Um es zu benutzen :
Das
printf
hier , um alle Dateien in einer Zeile jedem, im aktuellen Verzeichnis angezeigt und übergibt es ansed
.Hinweis : Dies ist nach alphabetischer Reihenfolge sortiert.
Weitere Infos von nützlich
pattern space
undhold space
HIER .grymoire.com hat wirklich gute Sachen zum
shell
Programmieren.quelle
h, n, H, x, p, q
bedeutet das? Sehr interessant.pattern space
&hold space
: grymoire.com/Unix/Sed.html#uh-56 oder in Französisch commentcamarche.net/faq/9536-sed-introduction-a-sed-part-iWenn Sie
grep
nur verwenden, können Sie die folgende Pipe erstellen:grep -A1 'Foo' input_file | grep -B1 'Bar' | grep 'Foo'
Der erste
grep
erhält alle Zeilen, die enthaltenFoo
, sowie die Zeile nach dem Spiel. Dann erhalten wir Zeilen, dieBar
sowohl die Zeile als auch die Zeile vor dem Match enthalten, und extrahieren schließlich die Zeilen aus dieser Ausgabe, die enthaltenFoo
.EDIT: Wie Manatwork hervorhob , gibt es einige problematische Fälle zu beachten . Obwohl es sich aufgrund der
grep
linienorientierten Funktionalität um eine interessante Herausforderung handelt, ist jede Lösung wahrscheinlich ein "Hack", und Sie sollten wahrscheinlich etwas verwenden,pcregrep
das für die jeweilige Aufgabe besser geeignet ist.quelle
find . -name '*.txt' | xargs grep -A1 'Foo' | grep -B1 'Bar'
Während ich Nathans Lösung mit bevorzuge
pcregrep
, ist hier die Lösung nur mit grepErklärung der Optionen:
-o
Nur passendes Teil drucken. Erforderlich, da durch Einfügen von-z
die gesamte Datei ausgedruckt wird (es sei denn, irgendwo ist eine \ 0 vorhanden).-z
Behandeln Sie die Eingabe als eine Reihe von Zeilen, die jeweils durch ein Null-Byte (das ASCII-NUL-Zeichen) anstelle einer neuen Zeile abgeschlossen werden.-P
Perl-Regex-SyntaxBEARBEITEN: Diese Version druckt ganze übereinstimmende Zeilen aus
quelle
-z
. Ein "(. *)" Vor und nach dem gesamten Ausdruck würde dazu führen, dass die gesamten übereinstimmenden Zeilen ausgegeben werden. Derzeit werden Teilzeichenfolgen vor "Foo" und nach "Bar" nicht angezeigt.Mit awk:
(Allgemeiner Hinweis zur awk-Einschränkung: Beachten Sie, dass einige Dateinamen "=" Zeichen enthalten müssen,
./filename
anstatt siefilename
an awk zu übergeben.)quelle