Eric Lilja
Eric Lilja

Reputation: 3593

Difference between grep and perl regex?

I have a problem with what I think is a difference in grep's regex and perl's regex. Consider the following little test:

$ cat testfile.txt 
A line of text
SOME_RULE = $(BIN)
Another line of text

$ grep "SOME_RULE\s*=\s*\$(BIN)" testfile.txt 
SOME_RULE = $(BIN)

$ perl -p -e "s/SOME_RULE\s*=\s*\$(BIN)/Hello/g" testfile.txt
A line of text
SOME_RULE = $(BIN)
Another line of text

As you can see, using the regex "SOME_RULE\s*=\s*$(BIN)", grep could find the match, but perl was unable to update the file using the same expression. How should I solve this problem?

Upvotes: 10

Views: 15190

Answers (4)

Hello World
Hello World

Reputation: 17

perl -ne '(/SOME_RULE\s*?=\s*?\$\(BIN\)/) && print' testfile.txt

If you want to modify use

perl -pe 's/SOME_RULE\s*?=\s*?\$\(BIN\)/Hello/' testfile.txt

Upvotes: 1

Prince John Wesley
Prince John Wesley

Reputation: 63688

You need to escape ( and )(Capturing group).

perl -p -e 's/SOME_RULE\s*=\s*\$\(BIN\)/Hello/g' testfile.txt

Actually you need it in Extended Regular Expression(ERE):

grep -E "SOME_RULE\s*=\s*\$\(BIN\)" testfile.txt

Upvotes: 2

Matthew Walton
Matthew Walton

Reputation: 9959

Perl's regex syntax is different to the POSIX regexes used by grep. In this case, you're falling foul of parentheses being metacharacters in Perl's regexes - they denote a capturing group.

You should have more success by altering the Perl regex:

s/SOME_RULE\s*=\s*\$\(BIN\)/Hello/g

which will then match the literal parentheses in the source text.

Upvotes: 0

William Pursell
William Pursell

Reputation: 212218

Perl wants the '(' and ')' to be escaped. Also, the shell eats the '\' on the '$', so you need:

$ perl -p -e "s/SOME_RULE\s*=\s*\\$\(BIN\)/Hello/g" testfile.txt

(or use single quotes--which is highly advisable in any case.)

Upvotes: 6

Related Questions