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

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
  • 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 Apr 17 at 22:20
  • @grep Indeed. I guess by "functionality" they mean "capability" (what it can do) rather than how it works. – Mikel Apr 18 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 \).
  • 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 Apr 17 at 22:16
  • What Mikel was saying was that echo aa | grep -E a{2} would happily work.... – steve Apr 17 at 22:18
  • @steve I don't see that that what's that quote is saying. – grep Apr 17 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 Apr 18 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 Apr 18 at 3:24

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.