Негативна відповідність із використанням grep (рядки відповідності, які не містять foo)


990

Я намагався опрацювати синтаксис для цієї команди:

grep ! error_log | find /home/foo/public_html/ -mmin -60

АБО:

grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60

Мені потрібно переглянути всі файли, які були змінені, крім названих error_log.

Я читав про це тут , але знайшов лише один not-регекс.


13
[^ error_log] ніколи ніколи не працюватиме, [] - це класи класів, взагалі regexp не є хорошими негативними моделями (якщо тільки двигун не реалізує негативні lookaheads).
Яап

Відповіді:


1755

grep -v ваш друг:

grep --help | grep invert  

-v, - невідповідні лінії виберіть невідповідні лінії

Ознайомтеся також із супутнім -L(доповненням -l).

-L, --файли без збігу друкують лише імена файлів FILE, що не відповідають


124
Варто зазначити, що для варіантів декількох (негативних) матчів -eможна використовувати:grep -v -e 'negphrase1' -e 'negphrase2'
Бабкен Варданян

31
Подібно до коментаря від @ Babken-Варданян Також - можливість використовувати труби, щоб приєднатися до декількох матчів, наприкладgrep -v 'negphrase1|negphrase2|negphrase3'
Ніколас Адамс

13
Останній коментар НЕ такий, як він буде шукати речі, які не відповідають обом, а не іншим. тобто якщо він відповідає одному, але не іншому, його все одно надрукують. Спробуйте обидва способи з не схожими рядками
Еван Ланглуа

7
@EvanLanglois - змушує греп інтерпретувати шаблон як розширений регулярний вираз із використанням -Eтворів, тобто grep -vE 'negphrase1|negphrase2|negphrase3'
Zlemini

1
@ OlleHärstedt, я думаю, що я неправильно зрозумів ваш сценарій у попередньому коментарі, наступне може бути те, що ви шукаєте grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u( чому перший греп ? , завжди є спосіб :))
Motti

139

Ви також можете використовувати awkдля цих цілей, оскільки це дозволяє чіткіше виконувати більш складні перевірки:

Рядки, що не містять foo:

awk '!/foo/'

Рядки, що не містять fooані bar:

awk '!/foo/ && !/bar/'

Рядки, що не містять ні, fooні barмістять foo2або bar2:

awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'

І так далі.


2
Це насправді досить круто. Вам навіть не доведеться вивчати повну мову awk, щоб згрупувати регулярне вираження з логічними операторами. Дякую за цю відповідь!
Пітер Т.

1
Саме те, що я шукав, дякую велике.
mmrs151

13

У вашому випадку, ймовірно, ви не хочете використовувати grep, але замість цього додаєте до команди find негативний застереження, наприклад

find /home/baumerf/public_html/ -mmin -60 -not -name error_log

Якщо ви хочете включити підстановку в ім’я, вам доведеться уникати їх, наприклад, виключати файли з суфіксом .log:

find /home/baumerf/public_html/ -mmin -60 -not -name \*.log
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.