Ответы:
Вы можете сделать это, используя -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
пригодится вместо того, чтобы передать несколько grep
s:
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"