63

I am trying to use grep with a regex to find lines in a file that match 1 of 2 possible strings. Here is my grep:

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

The above grep returns no results. However if I execute either:

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

or

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

I do match specific lines. Why is my OR regex not matching? Thanks in advance for the help!

92

With normal regex, the characters (, | and ) need to be escaped. So you should use

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

You don't need the escapes when you use the extended regex (-E)option. See man grep, section "Basic vs Extended Regular Expressions".

  • 10
    You can also use egrep instead of grep -E. – Riccardo Murri Sep 30 '11 at 13:19
  • 2
    @RiccardoMurri The answer of Michal states that egrep (and fgrep) are deprecated (even though they might still work). – Timo Dec 9 '17 at 9:44
26

If you want to use multiple branches (the | as or), then to be more compatible, it's better to explicit say you want to use "modern RE" aka. ERE.

To do so, use grep -E:

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

To learn more about RE, ERE and the whole "modern" ER story see man 7 regex.

Alternatively you can use egrep instead of grep, but as you can read from man grep:

egrep is the same as grep -E. fgrep is the same as grep -F

(...)

Direct invocation as either egrep or fgrep is deprecated

  • While direct invocation of egrep is deprecated it will work in most *nix variants. – Mark D Sep 30 '11 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.