Coincidencia negativa usando grep (coincide con líneas que no contienen foo)
Frecuentes
Visto 958,468 veces
1088
He estado tratando de resolver la sintaxis de este comando:
grep ! error_log | find /home/foo/public_html/ -mmin -60
O:
grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60
Necesito ver todos los archivos que se han modificado excepto los nombrados error_log
.
Lo he leído aquí, pero solo encontré uno not
-patrón regex.
3 Respuestas
1938
grep -v
es tu amigo:
grep --help | grep invert
-v, --invert-match seleccionar líneas no coincidentes
También echa un vistazo a los relacionados -L
(el complemento de -l
).
-L, --files-without-match solo imprime nombres de ARCHIVOS que no contienen coincidencias
Respondido el 19 de junio de 15 a las 23:06
Vale la pena mencionar que para coincidencias múltiples (negativas) -e
se puede utilizar la opción: grep -v -e 'negphrase1' -e 'negphrase2'
- babken vardanyan
Similar al comentario de @ Babken-Vardanyan También: capaz de usar tuberías para unir múltiples coincidencias, por ejemplo grep -v 'negphrase1|negphrase2|negphrase3'
- Nicolás Adams
El último comentario NO es el mismo, ya que buscará cosas que no coincidan con ambos en lugar de ninguno. es decir, si coincide con uno pero no con el otro, todavía se imprime. Pruébelo en ambos sentidos con cadenas no similares: Evan Langlois
@EvanLanglois: obligando a grep a interpretar el patrón como una expresión regular extendida usando -E
funciona, es decir grep -vE 'negphrase1|negphrase2|negphrase3'
- Zlemini
@ OlleHärstedt, creo que entendí mal su escenario en mi comentario anterior, lo siguiente puede ser lo que está buscando grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u
(¿Por qué el primer grep?, siempre hay una manera :)) - Motti
161
También puedes usar awk
para estos fines, ya que permite realizar comprobaciones más complejas de forma más clara:
Líneas que no contienen foo
:
awk '!/foo/'
Líneas que no contienen ninguno foo
ni bar
:
awk '!/foo/ && !/bar/'
Líneas que no contienen ninguno foo
ni bar
que contienen ya sea foo2
or bar2
:
awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'
Y así sucesivamente.
Respondido el 05 de diciembre de 18 a las 14:12
Eso es realmente genial. Ni siquiera tiene que aprender el lenguaje awk completo para agrupar expresiones regulares con operadores lógicos. ¡Gracias por esta respuesta! - Peter T.
18
En su caso, presumiblemente no desea usar grep, sino que agrega una cláusula negativa al comando de búsqueda, por ejemplo
find /home/baumerf/public_html/ -mmin -60 -not -name error_log
Si desea incluir comodines en el nombre, deberá escapar de ellos, por ejemplo, para excluir archivos con el sufijo .log:
find /home/baumerf/public_html/ -mmin -60 -not -name \*.log
respondido 02 nov., 15:13
mientras uno va a usar mmin
para buscar archivos modificados dentro 60 mins
, Utilizar -type f
también como se menciona aquí stackoverflow.com/a/33410471/2361131 - boquiabierto
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas regex grep or haz tu propia pregunta.
[^ error_log] nunca funcionaría de todos modos, [] son clases char, las expresiones regulares en general no son buenas para patrones negativos (a menos que el motor implemente búsquedas anticipadas negativas). - Jaap