Me gustaría obtener la coincidencia de múltiples patrones con AND implícito entre patrones, es decir, equivalente a ejecutar varios greps en una secuencia:
grep pattern1 | grep pattern2 | ...
Entonces, ¿cómo convertirlo en algo así?
grep pattern1 & pattern2 & pattern3
Me gustaría usar grep único porque estoy construyendo argumentos dinámicamente, por lo que todo tiene que encajar en una cadena. El uso del filtro es una característica del sistema, no grep, por lo que no es un argumento para ello.
No confunda esta pregunta con:
grep "pattern1\|pattern2\|..."
Esta es una coincidencia de múltiples patrones OR .
grep
regular-expression
Greenoldman
fuente
fuente

Respuestas:
agreppuede hacerlo con esta sintaxis:Con GNU
grep, cuando se construye con soporte PCRE, puede hacer:Con ast
grep:(agregar
.*s como<x>&<y>coincide con cadenas que coinciden con ambas<x>y<y>exactamente ,a&bnunca coincidiría, ya que no existe una cadena que pueda ser ambasaybal mismo tiempo).Si los patrones no se superponen, también puede hacer:
La mejor forma portátil es probablemente
awkcomo ya se mencionó:Con
sed:Tenga en cuenta que todas ellas tendrán una sintaxis de expresión regular diferente.
fuente
agrepsintaxis no funciona para mí ... ¿en qué versión se introdujo?agrepSe pueden encontrar versiones más nuevas (después de 1992) incluidas con glimpse / webglimpse . Posiblemente tenga una implementación diferente. Sin embargo, tuve un error con la versión ast-grep, la opción para expresiones regulares aumentadas es-X, no-A.agrep0.8.0 en Fedora 23. Esto parece ser diferente alagrepque usted hace referencia.agrep.awk '/p1/ && /p2/ {n++}; END {print 0+n}'No especificó la versión grep, esto es importante. Algunos motores regexp permiten múltiples coincidencias agrupadas por AND usando '&', pero esta es una característica no estándar y no portátil. Pero, al menos GNU grep no es compatible con esto.
OTOH simplemente puede reemplazar grep con sed, awk, perl, etc. (enumerados en orden de aumento de peso). Con awk, el comando se vería así
awk '/ regexp1 / && / regexp2 / && / regexp3 / {print; } 'y puede construirse para especificarse en la línea de comandos de manera fácil.
fuente
awkusa ERE, por ejemplo, el equivalente degrep -E, en oposición a los BRE quegrepusa.awkLas expresiones regulares se llaman ERE, pero de hecho son un poco idiosincrásicas. Aquí hay probablemente más detalles de los que a nadie le interesan: wiki.alpinelinux.org/wiki/Regexawk, simplemente saber que más es mejor).{ print; }parte no sea realmente necesaria o útil aquí.Si
patternscontiene un patrón por línea, puede hacer algo como esto:O esto coincide con subcadenas en lugar de expresiones regulares:
Para imprimir todo en lugar de ninguna línea de la entrada en el caso de que
patternsesté vacía, reemplaceNR==FNRconFILENAME==ARGV[1]o conARGIND==1ingawk.Estas funciones imprimen las líneas de STDIN que contienen cada cadena especificada como argumento como una subcadena.
gasignifica grep all egaiignora mayúsculas y minúsculas.fuente
Esta no es una muy buena solución, pero ilustra un "truco" algo genial
fuente
chained-grep()ofunction chained-grepnofunction chained-grep(): unix.stackexchange.com/questions/73750/…git grepAquí está la sintaxis que
git grepcombina varios patrones usando expresiones booleanas :El comando anterior imprimirá líneas que coincidan con todos los patrones a la vez.
Busca
man git-grepayuda.Ver también:
Para la operación OR , vea:
fuente
ripgrepAquí está el ejemplo usando
rg:Es una de las herramientas de grepping más rápidas, ya que está construida sobre el motor regex de Rust que utiliza autómatas finitos, SIMD y optimizaciones literales agresivas para que la búsqueda sea muy rápida.
Consulte también la solicitud de características relacionadas en GH-875 .
fuente
Aquí está mi opinión, y esto funciona para palabras en varias líneas:
Use
find . -type fseguido de tantos-exec grep -q 'first_word' {} \;y la última palabra clave con
-exec grep -l 'nth_word' {} \;-q-larchivos de programa silencioso / silencioso con coincidenciasLa siguiente lista devuelve nombres de archivos con las palabras 'conejo' y 'agujero' en ellos:
find . -type f -exec grep -q 'rabbit' {} \; -exec grep -l 'hole' {} \;fuente
Para encontrar TODAS las palabras (o patrones), puede ejecutar grep en el bucle FOR . La principal ventaja aquí es buscar en una lista de expresiones regulares .
EDITE mi respuesta con un ejemplo real:
Ahora vamos a ejecutarlo en este archivo:
fuente
ALLoperador, su código funciona comoORoperador, noAND. Y por cierto. para eso (OR) es una solución mucho más fácil dada en la pregunta.ANDoperador, lo que significa que el archivo es solo un golpe positivo si coincide con el patrón A y el patrón B y el patrón C y ...ANDEn su caso, el archivo es un golpe positivo si coincide patrón A o patrón B o ... ¿Ves la diferencia ahora?AND. Luego, debe volver a escribir el script para que se ejecute en varios archivos; entonces tal vez se dé cuenta de que la pregunta ya está respondida y su intento no trae nada a la mesa, lo siento.