Відповіді:
Ви можете зробити це, використовуючи -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)'набагато краще.
Я зрозумів питання як "Як я зіставляю слово, але виключаю інше", для якого одне рішення - це два грепи в серії: Перший греп - пошук потрібного "word1", другий "grep", виключаючи "word2":
grep "word1" | grep -v "word2"
У моєму випадку: мені потрібно розмежовувати "сюжет" і "#plot", який варіант "слова" грепа не буде робити ("#" не буквено-цифровий).
Сподіваюсь, це допомагає.
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с:
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, тому завантаження цього пакета буде набагато дорожчим, ніж звичайне grep.
grep забезпечує опцію '-v' або '--invert-match' для вибору невідповідних ліній.
напр
grep -v 'unwanted_pattern' file_name
Це виведе всі рядки з імені файлу file_name, який не має "небажаного_патронного"
Якщо ви шукаєте шаблон у кількох файлах всередині папки, ви можете скористатись параметром рекурсивного пошуку наступним чином
grep -r 'wanted_pattern' * | grep -v 'unwanted_pattern'
Тут grep спробує перерахувати всі випадки 'поисковой_паттерн' у всіх файлах з поточного каталогу і передати його другому грепу для фільтрації 'небажаного_паттерна'. '|' - pipe повідомить оболонку для підключення стандартного виводу лівої програми (grep -r 'want_pattern' *) до стандартного вводу правої програми (grep -v 'нежеланий_патерн').
У мене каталог з купою файлів. Я хочу знайти всі файли, які НЕ містять рядок "speedup", тому я успішно використав таку команду:
grep -iL speedup *
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"