Відповіді:
Ви можете зробити це, використовуючи -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"