Sin necesidad de instalar la variante grep pcregrep
, puede realizar una búsqueda de varias líneas con grep.
$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c
Explicación:
-P
activar perl-regexp para grep (una poderosa extensión de expresiones regulares)
-z
Trate la entrada como un conjunto de líneas, cada una terminada en un byte cero (el carácter ASCII NUL) en lugar de una nueva línea. Es decir, grep sabe dónde están los extremos de las líneas, pero ve la entrada como una gran línea. Tenga cuidado, esto también agrega un carácter NUL final si se usa con -o
, ver comentarios.
-o
imprimir solo coincidencia. Porque estamos usando -z
, todo el archivo es como una sola línea grande, por lo que si hay una coincidencia, se imprimirá todo el archivo; de esta manera no hará eso.
En expresión regular:
(?s)
activar PCRE_DOTALL
, lo que significa que .
encuentra cualquier carácter o salto de línea
\N
encuentra cualquier cosa excepto nueva línea, incluso con PCRE_DOTALL
activado
.*?
encuentra .
en modo no voraz, es decir, se detiene lo antes posible.
^
encontrar inicio de línea
\1
referencia inversa al primer grupo (\s*
). Este es un intento de encontrar la misma sangría del método.
Como puedes imaginar, esta búsqueda imprime el método principal en una C (*.c
) archivo fuente.
No soy muy bueno en grep. Pero su problema se puede resolver usando el comando AWK. Solo vea
awk '/select/,/from/' *.sql
El código anterior resultará de la primera ocurrencia de select
hasta la primera secuencia de from
. Ahora debe verificar si las declaraciones devueltas tienen customername
O no. Para esto puedes canalizar el resultado. Y puede usar awk o grep nuevamente.