Why does \d not match digits when using awk?

Viewed 635

I'm finding a behaviour I can't really explain with awk. Maybe it's a silly mistake but I can't figure it out.

I have a file called files with some random filenames.

$ cat -e files
3beds.txt$
file4.txt$
file3.txt$
dedo$
file5.txt$
texto5.txt$
metoo.txt$
34lions$
texto2.txt$
file1.txt$
7hello$
summer$
missing$
hello.mundo$
helloWorld.txt$
texto3$
awkvars$
texto4$
yes$
file2.txt$

I want to print only the filenames containing digits. I used the command:

awk '/\d/{print $0}' files

But my result was:

$ awk '/\d/{print $0}' files
3beds.txt
dedo
hello.mundo
helloWorld.txt

I'd really appreciate it if someone can explain to me why those lines are being printed. Thank you!

2 Answers

Clue: the four lines that matched were the four lines that contained "d".

So, clearly \d was being interpreted as a literal "d".

Why? Because awk's regex syntax is POSIX Extended Regular Expressions, not the Perl, PCRE or Ecma you might be used to. So \d does not stand for "digit" as you were expecting. You ended up using a backslash escape to force a literal "d".

The equivalent for \d in awk depends on the semantics you want[1]. [0-9] will match only the ten ASCII digits. You could also use the POSIX character class for digit inside a POSIX Bracket Expression, [[:digit:]]:

When used on strings with non-ASCII characters, the [:digit:] class may include digits in other scripts, depending on the locale.

My quotations are from regular-expressions.info, which has a wealth of info on the many syntaxes. This page took info from that page and turned it into a convenient table that compares 15 of them in great detail.


[1]: Even for regex engines that support the shorthand \d, the semantics can differ:

Since certain character classes are used often, a series of shorthand character classes are available. \d is short for [0-9]. In most flavors that support Unicode, \d includes all digits from all scripts. Notable exceptions are Java, JavaScript, and PCRE. These Unicode flavors match only ASCII digits with \d.

with awk, if you want to print only the lines containing digits, you can use this regexp instead:

awk '/[[:digit:]]/' file
3beds.txt$
file4.txt$
file3.txt$
file5.txt$
texto5.txt$
34lions$
texto2.txt$
file1.txt$
7hello$
texto3$
texto4$
file2.txt$
Related