1

The man page for grep reads (emphasis mine)

REGULAR EXPRESSIONS
       A regular expression is a pattern that describes a set of strings.  Regular expressions are
       constructed  analogously  to  arithmetic expressions, by using various operators to combine
       smaller expressions.

       grep understands three different versions of  regular  expression  syntax:  “basic”  (BRE),
       “extended”  (ERE)  and  “perl”  (PCRE).   In  GNU  grep there is no difference in available
       functionality between basic and extended syntaxes. 

Further down it reads

   Repetition
       A regular expression may be followed by one of several repetition operators:
       ?      The preceding item is optional and matched at most once.
       *      The preceding item will be matched zero or more times.
       +      The preceding item will be matched one or more times.
       {n}    The preceding item is matched exactly n times.
       {n,}   The preceding item is matched n or more times.
       {,m}   The preceding item is matched at most m times.  This is a GNU extension.
       {n,m}  The preceding item is matched at least n times, but not more than m times.

I think I'm using GNU's grep because the last line reads

User Commands                    GNU grep 2.16                         GREP(1)  

So, then, why does $ echo aa | grep a{2} fail to output anything while including -E works as expected?

2 Answers 2

2

The subtlety here is that while there is no difference in functionality, there is a difference in syntax. In particular:

  • in BRE, { and } are literal unless escaped, in which case they denote a quantifier expression

whereas

  • in ERE, { and } enclose quantifiers unless they are escaped, in which case they are literal.

So

$ echo aa | grep 'a\{2\}'    # BRE
aa

$ echo aa | grep -E 'a{2}'   # ERE
aa

If you don't enclose the expression in quotes, then you will need to backslash-escape the backslashes to prevent the shell from expanding them:

$ echo aa | grep a\\{2\\}    # BRE
aa
2
  • Thank you. I think it takes a very permissive interpretation to say syntax has nothing to do with functionality, but I accept that save. You answered everything I needed.
    – grep
    Commented Apr 17, 2019 at 22:20
  • @grep Indeed. I guess by "functionality" they mean "capability" (what it can do) rather than how it works.
    – Mikel
    Commented Apr 18, 2019 at 3:29
2

See the section further down in the man page

Basic vs Extended Regular Expressions

   In basic regular expressions the meta-characters ?, +, {, |, (, and )
   lose their special meaning; instead use the backslashed versions \?,
   \+, \{, \|, \(, and \).
5
  • I actually saw a reference to this in another source, and it still doesn't work. echo aa | grep a\{2\} won't print anything.
    – grep
    Commented Apr 17, 2019 at 22:16
  • What Mikel was saying was that echo aa | grep -E a{2} would happily work....
    – steve
    Commented Apr 17, 2019 at 22:18
  • @steve I don't see that that what's that quote is saying.
    – grep
    Commented Apr 17, 2019 at 22:18
  • @grep Your example doesn't work because your shell removes one level of escaping. You need echo aa | grep 'a\{2\}'
    – Mikel
    Commented Apr 18, 2019 at 3:23
  • 1
    @grep Sorry for the terse answer, I was on my phone. Yes, like steve says, that's what the man page was saying, albeit not as clearly as maybe it should. There's also a sentence "The following description applies to extended regular expressions; differences for basic regular expressions are summarized afterwards." that introduces things, implying that -- where there is a difference between grep and grep -E, the descriptions apply to grep -E unless stated otherwise.
    – Mikel
    Commented Apr 18, 2019 at 3:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .