2008-12-12 2 views
33

Я пытаюсь использовать grep с -v для инвертированного совпадения вместе с -e для регулярного выражения. У меня возникли проблемы с правилом синтаксиса.Использование grep с регулярным выражением, чтобы отфильтровать соответствия

Я пытаюсь что-то вроде

tail -f logFile | grep -ve "string one|string two" 

Если бы я сделать это таким образом, что не фильтровать Если изменить его

tail -f logFile | grep -ev "string one|string two" 

я

grep: string one|string two: No such file or directory 

Я пробовал использовать() или кавычки, но не смог найти ничего, что работает.

Как я могу это сделать?

ответ

50

Проблема заключается в том, что по умолчанию вам нужно сбежать от своих |, чтобы получить правильное чередование. То есть grep интерпретирует «foo | bar» как совпадающий только с буквенной строкой «foo | bar», тогда как шаблон «foo \ | bar» (с экранированным |) соответствует либо «foo», либо «bar».

Чтобы изменить это поведение, используйте флаг -e:

tail -f logFile | grep -vE 'string one|string two' 

В качестве альтернативы, использование задать расширенное, что эквивалентно ГРЭП -E:

tail -f logFile | egrep -v 'string one|string two' 

Кроме того, -e не является обязательным, если ваш шаблон не начинается с буквального дефиса. grep автоматически принимает первый аргумент без опции в качестве шаблона.

+0

хех, узнать что-то новое каждый день, я никогда раньше не замечал флаг -E на grep. – Jay 2008-12-12 20:58:48

+0

Это решение работает для MacOS? Я пытаюсь «история» grep -vE 'ng | npm'`, но он не работает должным образом. – Sergii 2018-01-02 06:04:21

5

Вам нужно бежать символ трубы когда -e используется:

tail -f logFile | grep -ve "string one\|string two" 

EDIT: или, как @Adam указал, вы можете использовать флаг -e:

tail -f logFile | grep -vE "string one|string two"