Risposte:
Puoi farlo usando l' opzione -v
(per --invert-match
) di grep come:
grep -v "unwanted_word" file | grep XXXXXXXX
grep -v "unwanted_word" file
filtrerà le linee che hanno il unwanted_word
e grep XXXXXXXX
elencherà 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
-v 'unwanted_word' --after N
non aiuta perché INCLUDE la linea e le N linee dopo.
-v
oppure --invert-match
seleziona linee non corrispondenti. Nel tuo caso grep -v 'unwanted_word' file
o grep --invert-match 'unwanted_word' file
.
git status -s |grep -v "folder_I_dont_care"
sun
, tranne quando lo è sunrise
, grep sun|grep -v sunrise
salta la riga che contiene entrambi sun
e sunrise
contemporaneamente, non è quello che voglio. grep -P 'sun(?!rise)'
è molto meglio.
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.
word1
.
Se grep
supporta l'espressione regolare Perl con l' -P
opzione 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 foo
trannefoo3
$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$
grep -v -P
funziona anche senza negazione nell'espressione regolare.
!
" . Grazie, grazie, grazie! Questo è quello che volevo!
La soluzione giusta è usare grep -v "word" file
, con il suo awk
equivalente:
awk '!/word/' file
Tuttavia, se ti capita di avere una situazione più complessa in cui vuoi, per esempio, XXX
apparire e YYY
non apparire, allora awk
è utile invece di connettere diversi grep
s:
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 XXX
o YYY
, ma non ZZZ
:
awk '(/XXX/ || /YYY/) && !/ZZZ/' file
eccetera.
grep -P
soluzione su file di grandi dimensioni.
grep -P
significa usare Perl regexp, quindi caricare quel pacchetto sarà molto più costoso di un normale grep
.
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').
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 *
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"