Se necesita expresión regular (grep) para búsqueda de varias líneas [duplicado]
Estoy ejecutando un grep
para buscar cualquier archivo *.sql que tenga la palabra select
seguida de la palabra customerName
seguida de la palabra from
. Esta declaración de selección puede abarcar muchas líneas y puede contener tabulaciones y nuevas líneas.
Probé algunas variaciones de lo siguiente:
$ grep -liIr --include="*.sql" --exclude-dir="\.svn*" --regexp="select[a-zA-Z0-
9+\n\r]*customerName[a-zA-Z0-9+\n\r]*from"
Esto, sin embargo, dura para siempre. ¿Alguien puede ayudarme con la sintaxis correcta, por favor?
Sin necesidad de instalar la variante grep pcregrep
, puedes realizar una búsqueda multilínea 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 con 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 línea grande. Tenga en cuenta que esto también agrega un carácter NUL final si se usa con -o
, consulte los comentarios.
-o
imprimir solo coincidencias. Debido a que estamos usando -z
, todo el archivo es como una única 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 nueva línea
\N
encontrar cualquier cosa excepto nueva línea, incluso con PCRE_DOTALL
activado
.*?
buscar .
en modo no codicioso, es decir, detenerse lo antes posible.
^
encontrar el inicio de la línea
\1
referencia al primer grupo ( \s*
). Este es un intento de encontrar la misma sangría de método.
Como puede imaginar, esta búsqueda imprime el método principal en un *.c
archivo fuente C ().
No soy muy bueno en grep. Pero tu problema se puede resolver usando el comando AWK . Sólo ve
awk '/select/,/from/' *.sql
El código anterior resultará desde la primera aparición de select
hasta la primera secuencia de from
. Ahora necesita verificar si las declaraciones devueltas se tienen customername
o no. Para esto puedes canalizar el resultado. Y puedo usar awk o grep nuevamente.