154

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
  • 9,188
  • 10
  • 67
  • 113
Ankur Agarwal
  • 23,692
  • 41
  • 137
  • 208
  • 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

246

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
  • 42,008
  • 16
  • 111
  • 154
Daenyth
  • 35,856
  • 13
  • 85
  • 124
  • 24
    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
24

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

Charles Ma
  • 47,141
  • 22
  • 87
  • 101