Ohne die grep-Variante pcregrep
installieren zu müssen , können Sie mit grep.
$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c
Erklärung:
-P
perl-regexp für grep aktivieren (eine mächtige Erweiterung regulärer Ausdrücke)
-z
Behandeln Sie die Eingabe als eine Reihe von Zeilen, die jeweils durch ein Null-Byte (das ASCII-NUL-Zeichen) anstelle eines Zeilenumbruchs abgeschlossen werden. Das heißt, grep weiß, wo die Enden der Zeilen sind, sieht die Eingabe jedoch als eine große Zeile. Beachten Sie, dass dies auch ein abschließendes NUL-Zeichen hinzufügt, wenn es mit -o
verwendet wird , siehe Kommentare.
-o
Druck nur passend. Weil wir -z
verwenden , ist die gesamte Datei wie eine einzige große Zeile, sodass bei einer Übereinstimmung die gesamte Datei gedruckt wird; Auf diese Weise wird es das nicht tun.
Im regulären Ausdruck:
(?s)
PCRE_DOTALL
aktivieren , was bedeutet, dass .
findet alle Zeichen oder Zeilenumbrüche
\N
alles außer Newline finden, sogar mit PCRE_DOTALL
aktiviert
.*?
finden Sie .
im nicht gierigen Modus, d. h. so schnell wie möglich beendet.
^
Zeilenanfang finden
\1
Rückverweis auf die erste Gruppe (\s*
). Dies ist ein Versuch, die gleiche Einrückung der Methode zu finden.
Wie Sie sich vorstellen können, gibt diese Suche die Hauptmethode in einem C (*.c
) Quelldatei.
Ich bin nicht sehr gut in grep. Aber Ihr Problem kann mit dem AWK-Befehl gelöst werden. Siehe einfach
awk '/select/,/from/' *.sql
Der obige Code ergibt sich aus dem ersten Auftreten von select
bis zur ersten Folge von from
. Jetzt müssen Sie überprüfen, ob zurückgegebene Anweisungen customername
haben oder nicht. Dazu können Sie das Ergebnis pipen. Und kann wieder awk oder grep verwenden.