3

I ran grep 'd(o|i)g' a.txt and a.txt contains dig but nothing was returned. Is this the right way to match dog or dig?

Andy Lester
  • 698
  • 7
  • 16
zmkm
  • 141
  • 3
  • 3
    See also [Why does my regular expression work in X but not in Y?](https://unix.stackexchange.com/q/119905/170373), though the fact that alternation (`|`) only works in ERE is kinda there in the middle of all the other stuff. – ilkkachu Feb 22 '22 at 14:29

3 Answers3

7

Yes, d(o|i)g is the correct way to do it. You can also do d[oi]g since you are dealing with single characters.

You need to use the -E flag on your grep call to get extended regexes.

$ cat a.txt
bird
dog
cat
dug
$ grep 'd(o|i)g' a.txt
$ grep -E 'd(o|i)g' a.txt
dog
Andy Lester
  • 698
  • 7
  • 16
  • 4
    Standard way of doing it for this particular case: `grep -e dog -e dig a.txt` or `grep 'd[io]g' a.txt`, as you propose. – Kusalananda Feb 21 '22 at 19:03
5

You need to escape the regex meta characters, like

> echo dig | grep "d\(o\|i\)g"
dig

, or you can switch to ERE ("extended RegEx"es):

echo dig | grep -E "d(o|i)g"
dig
RudiC
  • 8,889
  • 2
  • 10
  • 22
  • 6
    `\|` with Basic Regular Expressions (BRE) is a GNU extension. POSIX BRE don't have an alternation operator. POSIX EREs (with `grep -E`) do. – Stéphane Chazelas Feb 21 '22 at 17:12
3

You could also try grep 'd[io]g' but this only works for single characters.

user10489
  • 5,834
  • 1
  • 10
  • 22