Grep 'ИЛИ' проблема с регулярным выражением

65

Я пытаюсь использовать grep с регулярным выражением, чтобы найти строки в файле, которые соответствуют 1 из 2 возможных строк. Вот мой grep:

$ grep "^ID.*(ETS|FBS)" my_file.txt

Вышеуказанный grep не возвращает результатов. Однако, если я выполню либо:

$ grep "^ID.*ETS" my_file.txt  

или же

$ grep "^ID.*FBS" my_file.txt  

Я соответствую определенным линиям. Почему мое регулярное выражение OR не совпадает? Заранее спасибо за помощь!

dr.bunsen
источник

Ответы:

94

При нормальных условиях регулярных выражений, символов (, |и )необходимость быть экранированы. Так что вы должны использовать

$ grep "^ID.*\(ETS\|FBS\)" my_file.txt

Вам не нужны экранированные символы при использовании расширенной-E опции regex ( ). Смотрите man grepраздел " Basic vs Extended Regular Expressions".

rozcietrzewiacz
источник
10
Вы также можете использовать egrepвместо grep -E.
Риккардо Мурри
2
@RiccardoMurri В ответе Михала говорится, что egrep (и fgrep) устарели (даже если они все еще работают).
Тимо
27

Если вы хотите использовать несколько ветвей ( |как or), то для большей совместимости лучше явно сказать, что вы хотите использовать «современный RE», то есть. ERE.

Для этого используйте grep -E :

grep -E "^ID.*(ETS|FBS)" my_file.txt

Чтобы узнать больше о RE, ERE и всей «современной» истории ER см man 7 regex.

В качестве альтернативы вы можете использовать egrepвместо grep, но, как вы можете читать из man grep:

egrep такой же, как grep -E. fgrep такой же, как grep -F

(...)

Прямой вызов или как задать расширенную или fgrep является устаревшим

Михал Шрайер
источник
Хотя прямой вызов egrep устарел, он будет работать в большинстве вариантов * nix.
Марк Д