Grep множественный шаблон отрицательного соответствия


14

Итак, у меня есть куча журналов Apache с использованием стандартного формата журналов. Я хочу получить все строки журнала, которые не пришли из веб-сканера.

Допустим, у меня есть файл robot_patterns с записями вроде

Googlebot
msnbot-media
YandexBot
bingbot

Если я выполню команду, grep -f robot_patterns *.logя получу все записи ботами, соответствующими указанным выше шаблонам. Мой фактический список содержит ~ 30 записей ботов и агентов, которые я хочу игнорировать.

Но я хочу найти все записи, которые НЕ от ботов . Поэтому я стараюсь, grep -v -f robot_patterns *.logи результаты не возвращаются grep. Это не то, чего я ожидаю или желаю, и я не нахожу очевидного способа получить то, что я хочу. При использовании -vопции, объединенной с несколькими шаблонами в файле, grep будет возвращать совпадающую строку, только если она соответствует КАЖДОМУ шаблону.


Когда я попробовал это в моей системе, grep -v -f вел себя так, как надо, возвращая только строки, которые не соответствовали ни одному из шаблонов. Это было с (GNU grep) 2.14.56-1e3d. Какой grep вы используете?
wingedsubmariner

Я бегу GNU grep 2.6.3.
Zoredache

4
Я провел еще несколько тестов и обнаружил, что если в файле шаблонов есть пустая строка, она будет соответствовать каждой строке, в результате чего ни одна строка не будет возвращена с -v. Однако это не проблема с -F, и -F может ускорить grep для вашей задачи - возможно, стоит попробовать для вас.
wingedsubmariner

Завершающая пустая строка! Аааа ... Кажется, это проблема. Если вы хотите, вы должны добавить это как ответ.
Zoredache

Ответы:


8

Если в файле шаблонов есть пустая строка, она будет соответствовать каждой строке, в результате чего строки не будут возвращены -v. Это потому, что строки интерпретируются как регулярные выражения, и пустое регулярное выражение всегда будет совпадать.

Это не проблема, -Fоднако, grepигнорирует пустые строки с -F.
-Fзаставляет grepинтерпретировать строки как простые строки для поиска и может ускоряться, grepесли регулярные выражения не нужны.


1
В GNU fgrepигнорирование этой завершающей пустой строки было ошибкой, исправленной в 2.19 ( commit 2d3832e1ff772dc1a374bfad5dcc1338350cc48b , поэтому на нее не следует полагаться.
Стефан Шазелас

13

Можешь попробовать:

grep -vE 'Googlebot|msnbot-media|YandexBot|bingbot' yourlogfile

2
Добро пожаловать в Unix и Linux. У ОП есть список из примерно 30 строк, которые он хочет игнорировать, а четыре, которые он представил в качестве примеров, имеют среднюю длину в десять символов каждая, поэтому ваша команда может быть длиной более 300 символов. Это, вероятно, будет трудно поддерживать (и даже читать). Можете ли вы изменить свой ответ, руководствуясь списком строк OP? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... Вы заметили, что ответ найден? - ОП узнал, как получить свой оригинальный подход к работе.
G-Man говорит: «Восстановите Монику»

2
Зачем негативно оценивать мой ответ? : /
Орсиус

3
Отличный ответ. Имеет регулярное выражение ИЛИ и опция -vE оказалась полезной.
Кирт Карсон

3
Это ответ на вопрос, который большинство людей, вероятно, пытаются решить.
Perfi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.