¿Cómo puedo excluir una palabra con grep?

467

Necesito algo como:

grep ^"unwanted_word"XXXXXXXX
Juan
fuente
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"
Kanagavelu Sugumar

Respuestas:

802

Puede hacerlo usando la opción -v(for --invert-match) de grep como:

grep -v "unwanted_word" file | grep XXXXXXXX

grep -v "unwanted_word" filefiltrará las líneas que tienen unwanted_wordy grep XXXXXXXXsolo listará líneas con patrón XXXXXXXX.

EDITAR:

Según su comentario, parece que desea enumerar todas las líneas sin el unwanted_word. En ese caso, todo lo que necesitas es:

grep -v 'unwanted_word' file
codictorio
fuente
2
¿Qué sucede si también quiero excluir N líneas después de la línea con "palabra no deseada"? -v 'unwanted_word' --after Nno ayuda porque INCLUYE la línea y N líneas después.
Andrey Regentov
-vo --invert-matchseleccione líneas no coincidentes. En tu caso grep -v 'unwanted_word' fileo grep --invert-match 'unwanted_word' file.
adamski.pro
Quiero ignorar una línea arriba y una línea abajo con un patrón coincidente. ¿Cómo puedo lograrlo?
Kanji Viroja
Impresionante, uso esto en git para examinar rápidamente el estado de mi repositorio, funciona como un encanto:git status -s |grep -v "folder_I_dont_care"
benjaminz
3
Extraño, es la respuesta principal, ¡pero en algunos casos está mal! Si quiero encontrar sun, excepto cuando es así sunrise, grep sun|grep -v sunrisesalta la línea que contiene ambos suny sunriseal mismo tiempo, eso no es lo que quiero. grep -P 'sun(?!rise)'es mucho mejor.
Greene
86

Entendí la pregunta como "¿Cómo hago coincidir una palabra pero excluyo otra?", Para lo cual una solución es dos greps en serie: primer grep encontrando la "palabra1" deseada, segundo grep excluyendo "word2":

grep "word1" | grep -v "word2"

En mi caso: necesito diferenciar entre "plot" y "#plot", que la opción "palabra" de grep no hará ("#" no es alfanumérico).

Espero que esto ayude.

JPGConnolly
fuente
16
Debe invertir el orden para resaltar word1.
Matthew leyó el
1
Supongo que aclararía agregar un marcador de posición para el nombre del archivo a ese ejemplo
patrick
39

Si grepadmite la expresión regular de Perl con la -Popción que puede hacer (si es bash; si es tcsh, deberá escapar de !):

grep -P '(?!.*unwanted_word)keyword' file

Manifestación:

$ cat file
foo1
foo2
foo3
foo4
bar
baz

Hagamos ahora una lista de todos fooexceptofoo3

$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$ 
codictorio
fuente
Gracias por esto, muy útil! Me gustaría mencionar que el comando grep
distingue entre
2
Tenga en cuenta que grep -v -Ptambién funciona sin negación en la expresión regular.
cybersoft
"si bash ... tendrás que escapar del !" . ¡Gracias, gracias, gracias! ¡Eso es lo que quería!
Gabriel Staples
36

La solución correcta es usar grep -v "word" file, con su awkequivalente:

awk '!/word/' file

Sin embargo, si tiene una situación más compleja en la que desea, por ejemplo, XXXaparecer y YYY no aparecer, entonces awkresulta útil en lugar de canalizar varios greps:

awk '/XXX/ && !/YYY/' file
#    ^^^^^    ^^^^^^
# I want it      |
#            I don't want it

Incluso puedes decir algo más complejo. Por ejemplo: quiero esas líneas que contienen XXXo YYY, pero no ZZZ:

awk '(/XXX/ || /YYY/) && !/ZZZ/' file

etc.

fedorqui 'así que deja de dañar'
fuente
2
Parece ser mucho más rápido que la grep -Psolución en archivos grandes.
MBR
@MBR grep -Psignifica usar Perl regexp, por lo que cargar ese paquete será mucho más costoso de lo normal grep.
fedorqui 'SO deja de dañar'
10

Invierta la coincidencia utilizando grep -v:

grep -v "unwanted word" file pattern
garima
fuente
6

grep proporciona la opción '-v' o '--invert-match' para seleccionar líneas no coincidentes.

p.ej

grep -v 'unwanted_pattern' file_name

Esto generará todas las líneas del archivo nombre_archivo, que no tiene 'patrón_no deseado'.

Si está buscando el patrón en varios archivos dentro de una carpeta, puede usar la opción de búsqueda recursiva de la siguiente manera

grep -r 'wanted_pattern' * | grep -v 'unwanted_pattern'

Aquí grep intentará enumerar todas las apariciones de 'wanted_pattern' en todos los archivos desde el directorio actual y pasarlo al segundo grep para filtrar el 'unwanted_pattern'. '|' - pipe le dirá a shell que conecte la salida estándar del programa izquierdo (grep -r 'wanted_pattern' *) a la entrada estándar del programa derecho (grep -v 'unwanted_pattern').

Shriganesh Shintre
fuente
4

La -vopción le mostrará todas las líneas que no coinciden con el patrón.

grep -v ^unwanted_word
st0le
fuente
-5

Tengo un directorio con un montón de archivos. Quiero encontrar todos los archivos que NO contienen la cadena "speedup", así que utilicé con éxito el siguiente comando:

grep -iL speedup *
pjrieger
fuente
1
Desde la página de manual: "-L, --files-without-match Suprime la salida normal; en su lugar, imprima el nombre de cada archivo de entrada desde el que normalmente no se habría impreso ninguna salida. El escaneo se detendrá en la primera coincidencia " . por mí) ¡Así que ten cuidado con esto!
xuiqzy