Angenommen, ich möchte einen ganzen Baum nach allen CPP-Dateien durchsuchen, in denen "Foo" vorkommt. Ich könnte tun:
find . -name "*.cpp" | xargs grep "Foo"
Angenommen, ich möchte nur die Fälle auflisten, in denen eine andere Zeichenfolge, z. B. "Bar", nicht innerhalb von 3 Zeilen des vorherigen Ergebnisses auftritt.
Also zwei Dateien gegeben:
a.cpp
1 Foo
2 qwerty
3 qwerty
b.cpp
1 Foo
2 Bar
3 qwerty
Ich möchte eine einfache Suche erstellen, bei der "Foo" von a.cpp gefunden wird, "Foo" von b.cpp jedoch nicht.
Gibt es eine Möglichkeit, dies auf relativ einfache Weise zu erreichen?
Antworten:
Mit
pcregrep
:Der Schlüssel befindet sich in der
-M
Option, diepcregrep
für mehrere Zeilen eindeutig ist und zum Abgleichen mehrerer Zeilen verwendet wird (pcregrep
zieht bei Bedarf mehr Daten aus der Eingabedatei, wenn der RE dies erfordert).(?!...)
ist der Perl / PCRE-RE-Operator mit negativer Vorausschau.Foo(?!...)
stimmt übereinFoo
, solange...
nicht mit dem Folgenden übereinstimmt....
Sein(?:.*\n){0,2}.*Bar
(.
nicht mit einem Zeilenumbruchzeichen übereinstimmend), dh 0 bis 2 Zeilen, gefolgt von einer Zeile mitBar
.quelle
pcregrep
? Ich habe noch nie davon gehört.(?!...)
negativer Vorausschau vertrautperl
sind.Macht nichts, verwenden Sie einfach
pcregrep
wie vorgeschlagen von @StephaneChazelas.Das sollte funktionieren:
Die Idee ist, den
-A
Schalter von grep zu verwenden , um die übereinstimmenden Zeilen und die N folgenden Zeilen auszugeben. Sie übergeben das Ergebnis dann durch agrep Bar
und wenn dies nicht übereinstimmt (exit> 0), geben Sie den Namen der Datei wieder.Wenn Sie wissen, dass Sie vernünftige Dateinamen haben (keine Leerzeichen, neuen Zeilen oder andere seltsame Zeichen), können Sie Folgendes vereinfachen:
Beispielsweise:
Beachten Sie, dass dies
c.cpp
trotz Enthalten zurückgegeben wird,Bar
da die Zeile mitBar
mehr als 3 Zeilen danach istFoo
. Sie können die Anzahl der zu durchsuchenden Zeilen steuern, indem Sie den Wert ändern, der an Folgendes übergeben wird-A
:Hier ist eine kürzere (vorausgesetzt, Sie verwenden
bash
):WICHTIG
Wie Stephane Chazelas in den Kommentaren hervorhob, drucken die oben genannten Lösungen auch Dateien, die überhaupt nicht enthalten sind
Foo
. Dieser vermeidet das:quelle
Foo
. Sie haben fehlende Anführungszeichen.Foo
und ich habe das behoben, aber ich sehe Ihren Standpunkt nicht in Bezug auf mehrere Instanzen vonFoo
. Es sollte richtig mit ihnen umgehen.Ungetestet bin ich auf meinem Handy:
sowas in der Art.
quelle