142

This does not generate any output. How come?

$ echo 'this 1 2 3' | grep '\d\+'

But these do:

$ echo 'this 1 2 3' | grep '\s\+'
this 1 2 3

$ echo 'this 1 2 3' | grep '\w\+'
this 1 2 3
Iulian Onofrei
  • 8,409
  • 9
  • 67
  • 106
Ankur Agarwal
  • 21,824
  • 36
  • 127
  • 196
  • 2
    None of those work for me (Solaris). – spraff Aug 01 '11 at 16:07
  • Me neither. (Cygwin) Did you mean to have `\+`? What does that mean? – Eric Wilson Aug 01 '11 at 16:10
  • yes, I am on Ubuntu 10.04 , using bash. For BRE in grep you have to escape some characters. Try "Basic vs Extended Regular Expressions " in man grep. – Ankur Agarwal Aug 01 '11 at 16:12
  • 2
    @FarmBoy: `+` in a regex means "one or more of the previous token". In this case it's escaped because that's the syntax required by `grep`'s default regex engine. – Daenyth Aug 01 '11 at 16:13
  • @Daenyth I can't believe that I've been able to `grep` for years without realizing that `+` needs to be escaped. Thanks. – Eric Wilson Aug 01 '11 at 16:49
  • 2
    @FarmBoy: `+` needs to be escaped if you're using `grep`; if you're using `egrep`, it doesn't. `grep -E` is equivalent to `egrep` (at least for the GNU version). – Keith Thompson Aug 01 '11 at 21:02
  • See also https://stackoverflow.com/questions/18514135/bash-regular-expression-cant-seem-to-match-any-of-s-s-d-d-w-w-etc/48898886#48898886 (the question is about Bash, but many of the observations readily transfer to `grep`, `sed`, Awk, etc). – tripleee Nov 16 '21 at 16:10

2 Answers2

230

As specified in POSIX, grep uses basic regular expressions, but \d is part of a Perl-compatible regular expression (PCRE).

If you are using GNU grep, you can use the -P option, to allow use of PCRE regular expressions. Otherwise you can use the POSIX-specified [[:digit:]] character class in place of \d.

echo 1 | grep -P '\d'
# output: 1
echo 1 | grep '[[:digit:]]'
# output: 1
miken32
  • 39,644
  • 15
  • 91
  • 133
Daenyth
  • 33,666
  • 12
  • 82
  • 120
  • 20
    BSD grep's -E mode includes \d. But GNU grep's -E mode does not. That's so glaring I'm shocked I'm just discovering it now. – Keith Tyler Jun 23 '16 at 00:20
  • 1
    > BSD grep's -E mode includes \d. But GNU grep's -E mode does not. That's so glaring I'm shocked I'm just discovering it now. This just bit me on a git commit message validation script. I was very surprised \d was the culprit. – austinbruch Oct 21 '19 at 15:55
21

Try this $ echo 'this 1 2 3' | grep '[0-9]\+'

Charles Ma
  • 44,439
  • 22
  • 83
  • 99