Se necesita expresión regular (grep) para búsqueda de varias líneas [duplicado]

Resuelto Ciaran Archer asked hace 14 años • 3 respuestas

Estoy ejecutando un greppara buscar cualquier archivo *.sql que tenga la palabra selectseguida de la palabra customerNameseguida 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?

Ciaran Archer avatar Sep 15 '10 19:09 Ciaran Archer
Aceptado

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:

-Pactivar perl-regexp para grep (una poderosa extensión de expresiones regulares)

-zTrate 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.

-oimprimir 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

\Nencontrar cualquier cosa excepto nueva línea, incluso con PCRE_DOTALLactivado

.*?buscar .en modo no codicioso, es decir, detenerse lo antes posible.

^encontrar el inicio de la línea

\1referencia 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 *.carchivo fuente C ().

albfan avatar Aug 23 '2011 20:08 albfan

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 selecthasta la primera secuencia de from. Ahora necesita verificar si las declaraciones devueltas se tienen customernameo no. Para esto puedes canalizar el resultado. Y puedo usar awk o grep nuevamente.

Amit avatar Sep 15 '2010 13:09 Amit