Sans avoir besoin d'installer la variante grep pcregrep
, vous pouvez faire une recherche multiligne avec grep.
$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c
Explication :
-P
activer perl-regexp pour grep (une extension puissante des expressions régulières)
-z
Traitez l'entrée comme un ensemble de lignes, chacune terminée par un octet zéro (le caractère ASCII NUL) au lieu d'une nouvelle ligne. C'est-à-dire que grep sait où se trouvent les extrémités des lignes, mais voit l'entrée comme une seule grande ligne. Attention, cela ajoute également un caractère NUL à la fin s'il est utilisé avec -o
, voir les commentaires.
-o
imprimer uniquement la correspondance. Parce que nous utilisons -z
, le fichier entier est comme une seule grande ligne, donc s'il y a une correspondance, le fichier entier sera imprimé ; de cette façon, il ne le fera pas.
Dans l'expression rationnelle :
(?s)
activer PCRE_DOTALL
, ce qui signifie que .
trouve n'importe quel caractère ou retour à la ligne
\N
trouver quoi que ce soit sauf une nouvelle ligne, même avec PCRE_DOTALL
activé
.*?
trouver .
en mode non gourmand, c'est-à-dire s'arrête dès que possible.
^
trouver le début de la ligne
\1
backreference au premier groupe (\s*
). Ceci est un essai pour trouver la même indentation de méthode.
Comme vous pouvez l'imaginer, cette recherche imprime la méthode principale dans un C (*.c
) fichier source.
Je ne suis pas très bon en grep. Mais votre problème peut être résolu en utilisant la commande AWK. Il suffit de voir
awk '/select/,/from/' *.sql
Le code ci-dessus résultera de la première occurrence de select
jusqu'à la première séquence de from
. Vous devez maintenant vérifier si les instructions renvoyées ont customername
ou non. Pour cela, vous pouvez diriger le résultat. Et peut utiliser à nouveau awk ou grep.