2012-05-02 20 views
100

Estoy pasando una lista de patrones regex a grep para comparar con un archivo syslog. Por lo general, coinciden con una dirección IP y entrada de registro;Grep regex que NO contiene cadena

grep "1\.2\.3\.4.*Has exploded" syslog.log 

Es sólo una lista de patrones como la parte "1\.2\.3\.4.*Has exploded" estoy pasando, en un bucle, por lo que no puede pasar "-v", por ejemplo.

Estoy confundido tratando de hacer lo contrario de lo anterior, NO coinciden las líneas con una cierta dirección IP y el error por lo que "! 1.2.3.4. * Ha explotado" coincidirá con las líneas syslog para nada que no sea 1.2.3.4 diciendo me ha explotado. I debe ser capaz de incluir una IP para NO coincidir.

He visto varias publicaciones similares en StackOverflor pero utilizan patrones de expresiones regulares que parece que no puedo trabajar con grep. ¿Alguien puede proporcionar un ejemplo de trabajo para grep por favor?

ACTUALIZACIÓN: Esto está sucediendo en un script como este;

patterns[1]="1\.2\.3\.4.*Has exploded" 
patterns[2]="5\.6\.7\.8.*Has died" 
patterns[3]="\!9\.10\.11\.12.*Has exploded" 

for i in {1..3} 
do 
grep "${patterns[$i]}" logfile.log 
done 
+0

¿Quiere decir que a veces * * desea hacer coincidir un patrón, pero otras veces desea hacer coincidir todo * * excepto un cierto patrón? (Esto parece un requisito extraño, pero lo que sea). En ese caso, ¿por qué no iteras sobre dos listas diferentes de patrones? – beerbajay

+0

Bueno, no estoy muy bien informado sobre expresiones regulares; No quiero grep para "Ha explotado" porque no quiero saber esto sobre cada dispositivo de registro, por lo que de alguna manera puedo grep para "Ha explotado" y! 9.10.11.12 en una declaración? – jwbensley

+0

Si es absolutamente necesario que lo haga en una sola declaración, las miradas negativas son el camino a seguir, como sugiere Neil. Vea mi comentario allí. – beerbajay

Respuesta

183

grep partidos, grep -v hace el inverso. Si necesita "Un partido pero no B" que suelen utilizar tuberías:

grep "${PATT}" file | grep -v "${NOTPATT}" 
+0

Esto va en el medio de un ciclo como lo mencioné y estoy pasando el PATRÓN a grep, así que no puedo usar "-v" como mencioné. Solo estoy dando vueltas alrededor de una lista de PATRONES y pasando a grep. – jwbensley

+1

Puede usar '-v' y puede usarlo en un bucle. Quizás necesite ser más específico sobre sus limitaciones, o quizás tenga una idea errónea sobre cómo debería funcionar su script. Intenta publicar un código. – beerbajay

+0

Gracias beerbajay, he agregado un código recortado a la publicación original para dar contexto. ¿Ves lo que quiero decir ahora? – jwbensley

9
(?<!1\.2\.3\.4).*Has exploded 

Tiene que ejecutar esto con -P tener de búsqueda hacia atrás negativo (Perl expresiones regulares), por lo que el comando es:

grep -P '(?<!1\.2\.3\.4).*Has exploded' test.log 

Pruebe esto. Utiliza el lookbehind negativo para ignorar la línea si está precedida por 1.2.3.4. ¡Espero que ayude!

+1

Estoy bastante seguro de que 'grep' no es compatible con lookaround. A menos que esté usando Gnu 'grep' y use el parámetro' --P' para hacer que use un motor PCRE. –

+0

No, grep no es compatible con este tipo de Regex; $ grep -P (? <\! 1 \ .2 \ .3 \ .4) test.log -bash: error de sintaxis cerca del token inesperado '(' – jwbensley

+0

Necesitará citar la expresión regular si contiene caracteres que sería interpretado por el intérprete de comandos. – beerbajay

2
patterns[1]="1\.2\.3\.4.*Has exploded" 
patterns[2]="5\.6\.7\.8.*Has died" 
patterns[3]="\!9\.10\.11\.12.*Has exploded" 

for i in {1..3} 
do 
grep "${patterns[$i]}" logfile.log 
done 

debe ser el mismo que el

egrep "(1\.2\.3\.4.*Has exploded|5\.6\.7\.8.*Has died)" logfile.log | egrep -v "9\.10\.11\.12.*Has exploded"  
Cuestiones relacionadas