Reputation: 1145
I have a quick question:
Suppose I have a file contains:
abc$
$
$abc
and then I use grep "c\$" filename, then I got abc$ only. But if I use grep "c\\$", I got abc$.
I am pretty confused, doesn't back slash already turn off the special meaning of $? So grep "c\$" filename return me the line abc$?
Really hope who can kindly give me some suggestion.
Many thanks in advance.
Upvotes: 0
Views: 396
Reputation: 6240
Sign $
has special meaning in regexp patterns as the end of line, so when you use double quotes
grep "c\$"
the string expanded as two characters c
and $
and grep
thinks that it is regexp clause c'mon, find all lines with 'c' at the end.
In case of singe quotes, all characters treated as each one, i.e.
grep 'c\$'
command will have three characters c
, \
and $
. So grep
will got all those symbols at its input and therefore he gets escaped special $
symbol, i.e. as \$
and do what you have expected.
Upvotes: 0
Reputation: 785146
I would suggest using fgrep
if you want to search for literal $
and avoid escaping $
(which means end of line):
fgrep 'abc$' <<< 'abc$'
gives this output:
abc$
PS: fgrep
is same as grep -F
and as per the man grep
-F, --fixed-strings Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.
Upvotes: 0
Reputation: 107040
The double quotes are throwing you off. That allows the shell to expand meta-characters. On my Linux box using single quotes only:
$ grep 'abc$' <<<'abc$'
$ grep 'abc\$' <<<'abc$'
$ grep 'abc\$' <<<"abc$"
abc$
$ grep 'abc$' <<<'abc$'
$ grep 'abc\\$' <<<'abc$'
$
Note that the only grep
in the five commands above that found the pattern (and printed it out) was abc\$
. If I didn't escape the $
, it assumed I was looking for the string abc
that was anchored to the end of the line. When I put a single backslash before the $
, it recognized the $
as a literal character and not as a end of line anchor.
Note that the $
as an end of line anchor has some intelligence. If I put the $
in the middle of a regular expression, it's a regular character:
$ grep 'a$bc' <<<'a$bc'
a$bc
$ grep 'a\$bc' <<<'a$bc'
a$bc
Here, it found the literal string a$bc
whether or not i escaped the $
.
Tried things with double quotes:
$ grep "abc\$" <<<'abc$'
$ grep "abc\\$" <<<'abc$'
abc$
The single \
escaped the $
as a end of line anchor. Putting two \\
in front escaped the $
as a non-shell meta-character and as a regular expression literal.
Upvotes: 2
Reputation: 123498
If you're tempted to think that $
need to be escaped, then it's not so.
From the GNU grep manual, you'd figure:
The meta-characters that need to be escaped while using basic regular expressions are ?
, +
, {
, |
, (
, and )
.
Upvotes: 1