Come posso escludere una parola con grep?


Risposte:


802

Puoi farlo usando l' opzione -v(per --invert-match) di grep come:

grep -v "unwanted_word" file | grep XXXXXXXX

grep -v "unwanted_word" filefiltrerà le linee che hanno il unwanted_worde grep XXXXXXXXelencherà solo le linee con motivo XXXXXXXX.

MODIFICARE:

Dal tuo commento sembra che tu voglia elencare tutte le righe senza il unwanted_word. In tal caso, tutto ciò che serve è:

grep -v 'unwanted_word' file

2
e se volessi escludere N righe dopo la riga anche con "parole indesiderate"? -v 'unwanted_word' --after Nnon aiuta perché INCLUDE la linea e le N linee dopo.
Andrey Regentov,

-voppure --invert-matchseleziona linee non corrispondenti. Nel tuo caso grep -v 'unwanted_word' fileo grep --invert-match 'unwanted_word' file.
adamski.pro,

Voglio ignorare una riga sopra e una riga sotto con lo schema corrispondente quindi Come posso ottenerlo?
Kanji Viroja,

Fantastico, lo uso in git per esaminare rapidamente lo stato del mio repository, funziona come un incantesimo:git status -s |grep -v "folder_I_dont_care"
benjaminz,

3
Strano, è la risposta migliore, ma in alcuni casi è sbagliato! Se voglio trovare sun, tranne quando lo è sunrise, grep sun|grep -v sunrisesalta la riga che contiene entrambi sune sunrisecontemporaneamente, non è quello che voglio. grep -P 'sun(?!rise)'è molto meglio.
greene,

86

Ho capito la domanda come "Come posso abbinare una parola ma escluderne un'altra", per cui una soluzione è composta da due greps in serie: Primo grep che trova la "parola1" desiderata, secondo grep escluso "parola2":

grep "word1" | grep -v "word2"

Nel mio caso: ho bisogno di distinguere tra "trama" e "# trama" che l'opzione "parola" di grep non farà ("#" non è alfanumerico).

Spero che sia di aiuto.


16
È necessario invertire l'ordine per evidenziare word1.
Matteo Leggi il

1
Immagino che chiarirebbe aggiungere un segnaposto per il nome del file a quell'esempio
patrick

39

Se grepsupporta l'espressione regolare Perl con l' -Popzione che puoi fare (se bash; se tcsh dovrai sfuggire a !):

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

demo:

$ cat file
foo1
foo2
foo3
foo4
bar
baz

Elenchiamo ora tutti footrannefoo3

$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$ 

Grazie per questo, molto utile! Vorrei menzionare che il comando grep fa distinzione tra maiuscole e minuscole per impostazione predefinita
DocWiki,

2
Si noti che grep -v -Pfunziona anche senza negazione nell'espressione regolare.
cybersoft,

"se bash ... dovrai fuggire dal !" . Grazie, grazie, grazie! Questo è quello che volevo!
Gabriel Staples,

36

La soluzione giusta è usare grep -v "word" file, con il suo awkequivalente:

awk '!/word/' file

Tuttavia, se ti capita di avere una situazione più complessa in cui vuoi, per esempio, XXXapparire e YYY non apparire, allora awkè utile invece di connettere diversi greps:

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

Puoi persino dire qualcosa di più complesso. Ad esempio: desidero quelle righe contenenti o XXXo YYY, ma non ZZZ:

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

eccetera.


2
Sembra essere molto più veloce della grep -Psoluzione su file di grandi dimensioni.
MBR

@MBR grep -Psignifica usare Perl regexp, quindi caricare quel pacchetto sarà molto più costoso di un normale grep.
fedorqui "SO smettere di danneggiare"

10

Invertire la partita usando grep -v:

grep -v "unwanted word" file pattern

6

grep fornisce l'opzione '-v' o '--invert-match' per selezionare linee non corrispondenti.

per esempio

grep -v 'unwanted_pattern' file_name

Questo produrrà tutte le righe dal file nome_file, che non ha 'indesiderato_pattern'.

Se si cerca il modello in più file all'interno di una cartella, è possibile utilizzare l'opzione di ricerca ricorsiva come segue

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

Qui grep proverà a elencare tutte le occorrenze di "wanted_pattern" in tutti i file all'interno della directory corrente e passarlo al secondo grep per filtrare "unwanted_pattern". '|' - pipe dirà alla shell di collegare l'output standard del programma sinistro (grep -r 'wanted_pattern' *) all'input standard del programma destro (grep -v 'unwanted_pattern').


4

L' -vopzione ti mostrerà tutte le linee che non corrispondono al modello.

grep -v ^unwanted_word

-5

Ho una directory con un mucchio di file. Voglio trovare tutti i file che NON contengono la stringa "speedup", quindi ho usato con successo il seguente comando:

grep -iL speedup *

1
Dalla pagina man: "-L, --files-without-match Elimina l'output normale; stampa invece il nome di ciascun file di input dal quale non sarebbe stato normalmente stampato alcun output. La scansione si interromperà alla prima corrispondenza. " (Enfasi da parte mia) Quindi state attenti!
xuiqzy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.