
¿Existe alguna utilidad similar a grep que me permita realizar 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 vanilla grep y scripts bash adicionales, pero mi objetivo aquí es evitar tener que hacerlo.
Respuesta1
Hay muchas formas de utilizar grep
operadores lógicos.
El uso de múltiples
-e
opciones coincide con cualquier cosa que coincida con cualquiera de los patrones, dando alOoperación.Ejemplo:
grep -e pattern1 -e pattern2 filename
En expresiones regulares extendidas (
grep -E
), puede usar|
para combinar múltiples patrones con elOoperación.Ejemplo:
grep -E 'pattern1|pattern2' filename
grep -v
puede simular elNOoperación.No hayYoperador en
grep
, pero puedes simular por fuerza brutaYmediante el uso de múltiples patrones con|
.Ejemplo :
grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename
El ejemplo anterior coincidirá con todas las líneas que contienen ambos patrón1ypatrón2en cualquier orden. Esto se pone muy feo si hay más patrones para combinar.
Respuesta2
Con awk
, al igual que con perl
, tendrás que ajustar los términos en //
, pero se puede hacer:
awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))'
Tenga en cuenta que xor()
lo que es una extensión GNU no estándar es bit a bit xor
, no lógica. Está bien aquí ya que /regex/
solo devuelven 0 o 1.
Con otros awk
puedes definir una lógica xor()
como función:
function xor(a, b) {
return (a || b && ! (a && b))
}
O
function xor(a, b) {
return ((a && !b) || (b && !a))
}
Respuesta3
Podrías usar Perl:
perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'
Donde elinterruptoresson como sigue:
-w turns on warnings
-n runs perl against each line of input (looping)
-e executes perl passed in the command line
Respuesta4
Yo suelo encadenar grep
comandos para lograr un AND lógico:
grep expr1 filename | grep expr2
Creo que es bastante sencillo, parecido a Unix y elegante.
Luego puede combinar (como @Tushi explicó detalladamente) con la -E
opción de OR y -v
negar.
Su ejemplo específico es bastante desagradable y probablemente se beneficiaría de alguna utilidad más poderosa (consulte la respuesta de @muru).