Grep coincidencia negativa de patrón múltiple

14

Así que tengo un montón de registros de Apache con el uso del formato de registro estándar. Quiero obtener todas las líneas de registro que no provienen de un rastreador web.

Digamos que tengo un archivo robot_patterns con entradas como

Googlebot
msnbot-media
YandexBot
bingbot

Si ejecuto el comando grep -f robot_patterns *.log, obtendré todas las entradas de bots que coincidan con los patrones anteriores. Mi lista actual tiene ~ 30 entradas de bots y agentes que deseo ignorar.

Pero quiero encontrar todas las entradas que NO son de bots . Así que lo intento grep -v -f robot_patterns *.logy grep no devuelve ningún resultado. Esto no es lo que espero o deseo, y no estoy encontrando una manera obvia de obtener lo que quiero. Al usar la -vopción combinada con múltiples patrones en un archivo, grep solo devolverá una línea coincidente si coincide con CADA patrón.

Zoredache
fuente
Cuando probé esto en mi sistema, grep -v -f tuvo el comportamiento deseado, solo devolvió líneas que no coincidían con ninguno de los patrones. Esto fue con (GNU grep) 2.14.56-1e3d. ¿Qué grep estás usando?
wingedsubmariner
Estoy funcionando GNU grep 2.6.3.
Zoredache
44
Hice algunas pruebas más, y descubrí que si hay una línea vacía en el archivo de patrones, coincidirá con cada línea, causando que no se devuelva ninguna línea con -v. Sin embargo, esto no es un problema con -F, y -F puede acelerar grep para su tarea, puede valer la pena intentarlo.
wingedsubmariner
¡Una línea vacía al final! Argh ... Ese parece ser el problema. Si lo desea, debe agregar eso como respuesta.
Zoredache

Respuestas:

8

Si hay una línea vacía en el archivo de patrones, coincidirá con cada línea, por lo que no se devolverá ninguna línea -v. Esto se debe a que las líneas se interpretan como expresiones regulares, y una expresión regular vacía siempre coincidirá.

-FSin embargo, esto no es un problema porque grepignora las líneas vacías con -F.
-Fhace grepque interprete las líneas como cadenas simples para buscar y puede acelerar grepsi no se necesitan expresiones regulares.

Submarino alado
fuente
1
GNU fgrepignorando que la cadena vacía final era un error que se corrigió en 2.19 ( commit 2d3832e1ff772dc1a374bfad5dcc1338350cc48b , por lo que no debe confiar en él.
Stéphane Chazelas
13

Puedes probar:

grep -vE 'Googlebot|msnbot-media|YandexBot|bingbot' yourlogfile
Orsius
fuente
2
Bienvenido a Unix y Linux. El OP tiene una lista de aproximadamente 30 cadenas que quiere ignorar, y las cuatro que presentó como ejemplos tienen una longitud promedio de diez caracteres cada una, por lo que es probable que su comando tenga más de 300 caracteres. Es probable que esto sea difícil de mantener (e incluso de leer). ¿Puedes modificar tu respuesta para que sea manejada por la lista de cadenas del OP? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... PD: ¿Notó que se ha encontrado la respuesta? - El OP ha aprendido cómo lograr que su enfoque original funcione.
G-Man dice 'reinstalar a Monica' el
2
¿Por qué evaluar negativamente mi respuesta? : /
Orsius
3
Gran respuesta. Tiene regex OR y la opción -vE fue útil.
Kirt Carson
3
Esta es la respuesta a la pregunta que la mayoría de la gente probablemente está tratando de resolver.
Perfi