strange behaviour of grep in UNIX

2

0

When I type the command

$ grep \\\\h junk  

then the shell should interpret \\\\h as \\h - as the two pairs of \\ each become \ . grep in turn, should interpret \\h as \h as \\ becomes \, so grep should search for the pattern \h in junk, which it is doing successfully.

But it's not working for \\\\$. Why?

Happy Mittal

Posted 2010-04-16T11:12:46.950

Reputation: 279

@Happy: ok, i believe i see the difference. in this question and the other. reopening. please double-check that my edits are what you intended to say -- i've used markdown formatting for codeblocks (4-space-indent) and string literals (backticks), so that avoids having to type \\\\\\\\h just to see \\\\h. hope i got the numbers right. – quack quixote – 2010-04-16T11:53:03.187

better on superuser.com – YOU – 2010-04-16T11:14:47.673

Isn't $ some special symbol too? Try \\\$ – None – 2010-04-16T11:34:01.047

1@Draco Ater Unfortunately that's not enough, don't forget that the shell gets first bat against backslashed chars... which turns \$ into $, which grep then interprets as the EOL symbol. – David – 2010-04-16T11:36:25.753

Try using echo to see what input is going into grep. I.E., echo \\\$ will give output as \$. – Kevin Panko – 2010-04-16T15:42:20.130

Answers

6

To return lines with a dollar sign, another way without escapes is:

grep "[$]" file

To find lines with the literal \$:

grep "[\][$]" file

user31894

Posted 2010-04-16T11:12:46.950

Reputation: 2 245

Very nice! Testing in bash, you don't need quotes either! – David – 2010-04-16T11:44:25.460

2

Returns only lines with the dollar sign in it.

grep "\\$" application/bootstrap.php

Because $ is a regex command as well ( end of line ), you have to quote it to get the double slashes past your shell and into grep.

David

Posted 2010-04-16T11:12:46.950

Reputation: 161

1

Grep always uses \ to quote the next character, so \h simply becomes h in your example, since \h is not "special":

$ cat file
\a
a

$ grep \\a file
\a
a

$ grep \\\\a file
\a

Dan Andreatta

Posted 2010-04-16T11:12:46.950

Reputation: 211

As in your last example, grep \\a searches for \a, shouldn't \\$ be searched for $ because shell passes grep as \$ and grep converts it to $. am I correct? – Happy Mittal – 2010-04-16T11:44:24.197

As others have pointed out, $ matches the end of the string, so you have to quote it. If you want to search for the two characters '$', then grep needs \\\$, and quoting for the shell gives you \\\\\\$ – None – 2010-04-16T11:58:29.727

1

Assuming you're trying to match the character '$', the pattern:

[$]

is the easiest way to specify it without getting tangled up in multiple levels of character-escapes. Or if you're trying to match the two characters: '\$', then

[\\][$]

will do it.

JRobert

Posted 2010-04-16T11:12:46.950

Reputation: 6 128

1

\h is not a special escape for grep, so '\h' should find a \h in a file, which it does. The shell removes the first \ before grep sees it, as \ is special (type ls \\ and it says ls: : So such file or directory ). So to match "\h" in a file, use grep \h, or '\h' to avoid the first \ --> \ reduction by the shell.

Now \$ : \ is reduced to \ by the shell, and grep sees \$ and because $ is special in regexes (like +,.,* etc), \$ is a literal dollar sign, as a simple test file will show you. See the man page for re_format (7). So this matches all lines with a dollar sign.

So if you want to match a literal "\$" in a file, we need to think: \$ is unescaped by the shell to literal $, and \ to : try ls \\\$' and you get "ls: \$: No such file or directory". So ingrep \\$ file, grep sees \$ and interprets that as $ again... So we want grep to see \\\$ (which it will unescape again to \$), so we can put single quotes around that and avoid headaches, or escape all the special characters for the shell too:grep \\\\$ file`. This works.

That's why I almost always put single quotes around the first grep argument, so I only have to think about what grep will do, and not about the shell as well.

Henno

Posted 2010-04-16T11:12:46.950

Reputation: 639

0

Your shell is interpreting \\ as \, and $ as a first character of some control sequences, like variable names. Therefore \\\\ is interpreted by your shell as literal \\ (as you think), but $ needs to be escaped to be interpreted as literal character. Use \\\\\\\$ (seven backslashes) or '\\\$' (text in apostrophes is interpreted literally by shell).

liori

Posted 2010-04-16T11:12:46.950

Reputation: 3 044

sorry I mistakenly typed wrong question. Now I have edited it. Please explain answer. – Happy Mittal – 2010-04-16T11:38:40.750

But it's neither working with \\$(five backslashes), nor with '\$' – Happy Mittal – 2010-04-16T12:28:01.510

2Please explain "not working" with a reproducible case. i.e. what contains the file you are "grepping", what command you run, what result you got you aren't expecting. – jlliagre – 2010-04-16T12:43:10.883

0

Why can't you just grep '\\$'? Single quotes prevent almost all interpolation.

Daenyth

Posted 2010-04-16T11:12:46.950

Reputation: 5 742