grep returns "<regular expression>" No such file or directory

1.6k views Asked by At

I have the following regular expression to match a phone number. The regular expression works (123)123-123, but I am puzzled by the last result.

user@host: grep -l -v -f *.txt -E "(\d{3})-\d{3}-\d{3}"
f2.txt
f3.txt
f4.txt
grep: (\d{3})-\d{3}-\d{3}: No such file or directory

Why is grep searching the regular expression?

Here is the ls:

user@host:/tmp# ls
f1.txt  f2.txt  f3.txt  f4.txt  
1

There are 1 answers

1
Benjamin W. On BEST ANSWER

The grep usage is

grep [OPTION]... PATTERN [FILE]...

Your command expands to

grep -l -v -f f1.txt f2.txt f3.txt f4.txt -E "(\d{3})-\d{3}-\d{3}"

which is equivalent to

grep -f f1.txt -l -v -E f2.txt f3.txt f4.txt "(\d{3})-\d{3}-\d{3}"

which is "use the file f1.txt as a file containing patterns, and search the files f2.txt, f3.txt, f4.txt and (\d{3})-\d{3}-\d{3}. Apply options -l, -v and -E everywhere."

Maybe you meant

grep -l -v -E "(\d{3})-\d{3}-\d{3}" *.txt

instead?

The relevant part of the man page reads as follows:

-f FILE, --file=FILE
Obtain patterns from FILE, one per line. If this option is used multiple times or is combined with the -e (--regexp) option, search for all patterns given. The empty file contains zero patterns, and therefore matches nothing.

Side note: if you use -E, you have to escape literal parentheses. Also, \d is not supported as far as I can tell, so you'd have to use either

grep -P '\(\d{3}\)-\d{3}-\d{3}'

or

grep -E '\([[:digit:]]{3}\)-[[:digit:]]{3}-[[:digit:]]{3}'