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.