Ответы:
Вы можете сделать это, используя -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
-v 'unwanted_word' --after Nне помогает, потому что включает в себя строку и N строк после.
-vили --invert-matchвыберите несовпадающие строки. В вашем случае grep -v 'unwanted_word' fileили grep --invert-match 'unwanted_word' file.
git status -s |grep -v "folder_I_dont_care"
sun, за исключением случаев, когда это так sunrise, grep sun|grep -v sunriseпропускает строку, содержащую оба sunи sunriseсразу, это не то, что я хочу. grep -P 'sun(?!rise)'намного лучше.
Я понял вопрос как «Как мне сопоставить слово, но исключить другое», для которого одно решение состоит из двух последовательных greps: первый grep находит искомое «word1», второй grep исключает «word2»:
grep "word1" | grep -v "word2"
В моем случае: мне нужно различать «plot» и «#plot», что не подходит для «слова» в grep («#» не является буквенно-цифровым).
Надеюсь это поможет.
word1.
Если вы 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
$
grep -v -Pтакже работает без отрицания в регулярном выражении.
!» . Спасибо Спасибо спасибо! Вот чего я хотел!
Правильное решение заключается в использовании 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
и т.п.
grep -Pрешение для больших файлов.
grep -Pозначает использование Perl regexp, поэтому загрузка этого пакета будет намного дороже обычного grep.
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').
У меня есть каталог с кучей файлов. Я хочу найти все файлы, которые НЕ содержат строку «ускорение», поэтому я успешно использовал следующую команду:
grep -iL speedup *
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"