¿Cómo puedo buscar un patrón multilínea en un archivo?
-
02-07-2019 - |
Pregunta
Necesitaba encontrar todos los archivos que contenían un patrón de cadena específico. La primera solución que viene a la mente es usar find canalizado con xargs grep :
find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'
Pero si necesito encontrar patrones que se extiendan en más de una línea, estoy atascado porque vanilla grep no puede encontrar patrones multilínea.
Solución
Entonces descubrí pcregrep que significa Expresiones regulares compatibles con Perl GREP .
Por ejemplo, necesita encontrar archivos en los que la variable ' _name ' sea seguida inmediatamente por la variable ' _description ':
find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'
Sugerencia: debe incluir el carácter de salto de línea en su patrón. Dependiendo de su plataforma, podría ser '\ n', \ r ',' \ r \ n ', ...
Otros consejos
¿Por qué no vas a awk :
awk '/Start pattern/,/End pattern/' filename
grep -P
también usa libpcre, pero es mucho más instalado. Para encontrar una sección completa de title
de un documento html, incluso si abarca varias líneas, puede usar esto:
grep -P '(?s)<title>.*</title>' example.html
Dado que el proyecto PCRE se implementa en el estándar perl, use la documentación de perl como referencia:
Aquí hay un ejemplo más útil:
pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html
Busca la etiqueta del título en un archivo html incluso si se extiende hasta 5 líneas.
Aquí hay un ejemplo de líneas ilimitadas:
pcregrep -Mi "(?s)<title>.*</title>" example.html
Con buscador de plata :
ag 'abc.*(\n|.)*efg'
Las optimizaciones de velocidad del buscador de plata posiblemente podrían brillar aquí.
Puede usar la alternativa grep tamizar aquí (descargo de responsabilidad: yo soy el autor).
Admite la coincidencia multilínea y limita la búsqueda a tipos de archivos específicos fuera de la caja:
sift -m --files '*.py' 'YOUR_PATTERN'
(busque en todos los archivos * .py el patrón de expresión regular multilínea especificado)
Está disponible para todos los principales sistemas operativos. Eche un vistazo a la página de ejemplos para ver cómo se puede usar para extraer valores de varias líneas de una Archivo XML.
Esta respuesta puede ser útil:
Regex (grep) para la búsqueda multilínea necesaria
Para encontrar recursivamente puedes usar los indicadores -R (recursivo) y --include (patrón GLOB). Ver:
Use grep --exclude / - incluye sintaxis para no grep a través de ciertos archivos
perl -ne 'print if (/begin pattern/../end pattern/)' filename
Usando ex
/ vi
y globstar option (sintaxis similar a awk
y sed
):
ex +"/string1/,/string3/p" -R -scq! file.txt
donde aaa
es tu punto de partida, y bbb
es tu texto final.
Para buscar recursivamente, intente:
ex +"/aaa/,/bbb/p" -scq! **/*.py
Nota: Para habilitar la sintaxis de **
, ejecute shopt -s globstar
(Bash 4 o zsh).
@Marcin: awk ejemplo no codicioso:
awk '{if (<*> ~ /Start pattern/) {triggered=1;}if (triggered) {print; if (<*> ~ /End pattern/) { exit;}}}' filename