grep con operadores lógicos

19

¿Existe una utilidad similar a grep que me permita hacer búsquedas grep con operadores lógicos? Quiero poder anidar y combinar las construcciones lógicas libremente. Por ejemplo, cosas como esta deberían ser posibles:

grep (term1 && term2) || (term1 && (term3 xor term4)) *

Me doy cuenta de que esto se puede hacer con vainilla grep y secuencias de comandos bash adicionales, pero mi objetivo aquí es evitar tener que hacer eso.


fuente

Respuestas:

12

Con awk, como con perl, tendrá que incluir los términos //, pero se puede hacer:

awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))' 
muru
fuente
28

Hay muchas formas de usar grepcon operadores lógicos.

  1. Se usa \|para separar múltiples patrones para la condición OR .

    Ejemplo: grep 'pattern1\|pattern2' filename

  2. Use la -Eopción para enviar múltiples patrones para la condición OR .

    Ejemplo: grep -E 'pattern1|pattern2' filename

  3. El uso de un solo -ecoincide con un solo patrón, pero el uso de múltiples -eopciones coincide con más de un patrón.

    Ejemplo: grep -e pattern1 -e pattern2 filename

  4. grep -vpuede simular la operación NOT .

  5. No hay ningún operador ANDgrep , pero puede simular la fuerza bruta AND utilizando la -Eopción

    Ejemplo: grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename

    El ejemplo anterior coincidirá con todas las líneas que contienen tanto pattern1 y pattern2 en cualquier orden.)

Thushi
fuente
1
-Eno es del todo equivalente al &&hecho de que es sensible al orden
iruvar 05 de
grep foo | grep bares una forma más general de hacer AND.
Kenster
2
+1 por explicar claramente que no existe un operador "AND" real, y que lo mejor que podemos hacer es simular un hack utilizando una estructura OR. Por supuesto, esto se volverá difícil de manejar con más de 3 términos, pero por dos términos funciona bien.
Eric Hepperle - CodeSlayer2010
grep -c -e MATCH1 -e MATCH2 es excelente cuando le interesan los recuentos de nombres de archivo.
andrej
4

Podrías usar perl:

perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'
michas
fuente
0
sed '/term1/!d;/term2/b' -e '/term3/!d;/term4/d' *

Creo que eso logra lo que intentas hacer. Se deletes de salida de cualquier línea que no coincide term1, se branchos de la secuencia de comandos (y por lo autoprints) cualquier línea que queda y que los partidos term2y para las líneas que permanecen elimina cualquier que no coinciden term3y de aquellos que lo hacen ningún partido term4.

sed las secuencias de comandos se evalúan en orden y todas las pruebas son booleanas, por lo que cualquier acción resultante de una prueba afectará directamente el comportamiento de las siguientes acciones.

mikeserv
fuente
0

Utilizo para encadenar grepcomandos para lograr un AND lógico:

grep expr1 filename | grep expr2

Creo que es bastante sencillo, similar a Unix y elegante.


Luego, puede combinar (como @Tushi explicó a fondo) con la -Eopción de OR y -vpara negar.

Su ejemplo específico es bastante desagradable y probablemente se beneficiaría de alguna utilidad más poderosa (vea la respuesta de @ muru).

Campa
fuente