Как я могу исключить одно слово с помощью grep?

467

Мне нужно что-то вроде:

grep ^"unwanted_word"XXXXXXXX
Джон
источник
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"
Канагавелу Сугамар

Ответы:

802

Вы можете сделать это, используя -v(для --invert-match) опцию grep как:

grep -v "unwanted_word" file | grep XXXXXXXX

grep -v "unwanted_word" fileбудет фильтровать строки, которые имеют unwanted_wordи grep XXXXXXXXбудет перечислять только строки с шаблоном XXXXXXXX.

РЕДАКТИРОВАТЬ:

Из вашего комментария похоже, что вы хотите перечислить все строки без unwanted_word. В этом случае все, что вам нужно, это:

grep -v 'unwanted_word' file
codaddict
источник
2
Что делать, если я хочу исключить N строк после строки с «нежелательным словом»? -v 'unwanted_word' --after Nне помогает, потому что включает в себя строку и N строк после.
Андрей Регентов
-vили --invert-matchвыберите несовпадающие строки. В вашем случае grep -v 'unwanted_word' fileили grep --invert-match 'unwanted_word' file.
adamski.pro
Я хочу игнорировать одну строку выше и одну строку ниже с соответствующим шаблоном. Как я могу этого достичь?
Кандзи Виройя
Круто, я использую это в git для быстрого просмотра статуса моего репо, работает как талисман:git status -s |grep -v "folder_I_dont_care"
benjaminz
3
Странно, это лучший ответ, но в некоторых случаях это неправильно! Если я хочу найти sun, за исключением случаев, когда это так sunrise, grep sun|grep -v sunriseпропускает строку, содержащую оба sunи sunriseсразу, это не то, что я хочу. grep -P 'sun(?!rise)'намного лучше.
Грин
86

Я понял вопрос как «Как мне сопоставить слово, но исключить другое», для которого одно решение состоит из двух последовательных greps: первый grep находит искомое «word1», второй grep исключает «word2»:

grep "word1" | grep -v "word2"

В моем случае: мне нужно различать «plot» и «#plot», что не подходит для «слова» в grep («#» не является буквенно-цифровым).

Надеюсь это поможет.

JPGConnolly
источник
16
Вы должны изменить порядок, чтобы получить подсветку word1.
Мэтью Прочитал
1
Я полагаю, было бы уточнить, чтобы добавить в этот пример заполнитель для имени файла
Патрик
39

Если вы grepподдерживаете регулярное выражение Perl с -Pопцией, которую вы можете сделать (если bash; если tcsh, вам нужно будет экранировать !):

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

Демо-версия:

$ cat file
foo1
foo2
foo3
foo4
bar
baz

Давайте теперь перечислим все fooкромеfoo3

$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$ 
codaddict
источник
Спасибо за это, очень полезно! Я хотел бы отметить, что по умолчанию команда grep чувствительна к регистру
DocWiki
2
Обратите внимание, что grep -v -Pтакже работает без отрицания в регулярном выражении.
cybersoft
«если буш ... тебе нужно сбежать !» . Спасибо Спасибо спасибо! Вот чего я хотел!
Габриэль Стейплс
36

Правильное решение заключается в использовании grep -v "word" file, с его awkэквивалентом:

awk '!/word/' file

Однако, если вам случится иметь более сложную ситуацию, в которой вы хотите, скажем, XXXпоявиться, а YYY не появиться, тогда вам awkпригодится вместо того, чтобы передать несколько greps:

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

Вы даже можете сказать что-то более сложное. Например: я хочу, чтобы эти строки содержали либо, XXXлибо YYY, но не ZZZ:

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

и т.п.

Федорки "ТАК прекратить вредить"
источник
2
Похоже, это намного быстрее, чем grep -Pрешение для больших файлов.
MBR
@MBR grep -Pозначает использование Perl regexp, поэтому загрузка этого пакета будет намного дороже обычного grep.
Федорки "ТАК прекратить причинять вред"
10

Инвертировать соответствие, используя grep -v:

grep -v "unwanted word" file pattern
Garima
источник
6

grep предоставляет опцию '-v' или '--invert-match' для выбора несовпадающих строк.

например

grep -v 'unwanted_pattern' file_name

Это выведет все строки из файла file_name, который не имеет «unwanted_pattern».

Если вы ищете шаблон в нескольких файлах внутри папки, вы можете использовать опцию рекурсивного поиска следующим образом

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

Здесь grep попытается перечислить все вхождения 'wanted_pattern' во всех файлах из текущего каталога и передать его второму grep, чтобы отфильтровать 'unwanted_pattern'. '|' - pipe сообщит оболочке подключить стандартный вывод левой программы (grep -r 'wanted_pattern' *) к стандартному вводу правой программы (grep -v 'unwanted_pattern').

Шриганеш Синтре
источник
4

-vВариант покажет вам все строки , которые не соответствуют шаблону.

grep -v ^unwanted_word
st0le
источник
-5

У меня есть каталог с кучей файлов. Я хочу найти все файлы, которые НЕ содержат строку «ускорение», поэтому я успешно использовал следующую команду:

grep -iL speedup *
pjrieger
источник
1
Со страницы man: «-L, --files-without-match Подавить нормальный вывод; вместо этого выведите имя каждого входного файла, из которого обычно не выводился бы вывод. Сканирование остановится при первом совпадении. » (Акцент от меня) Так что остерегайтесь этого!
xuiqzy