Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I could see that certain patterns in the GNU Grep can be enclosed within brackets and certain others need not be. For example, matching the beginning of a word works only if it is enclosed within quotes.

user@host:~/Desktop$ grep -E '\<H' test
Hello World
user@host:~/Desktop$ grep -E \<H test

[test contains the string Hello World]

But matching end and beginning of file works without dollar:

user@host:~/Desktop$ egrep d$ test
Hello World

Why is it so? And what is the rule?

share|improve this question
add comment

2 Answers 2

up vote 5 down vote accepted

The quotes are expanded by the shell, they determine what grep sees.

With grep -E '\<H', the characters between the single quotes are passed literally, so grep sees the regex \<H containing the beginning-of-word anchor \<.

With grep -E \<H, the backslash character removes the special meaning of < in the shell, and grep sees the regex <H. You would see matches for a line like <Hello>.

With grep -E <H, the < character would have its special meaning in the shell as a redirection character, so grep would receive the contents of the file called H on its standard input.

With grep 'd$' or grep d\$, the dollar sign is quoted so it reaches grep: the regex is d$, matching a d at the end of a line.

With grep d$ test, the $ sign is not followed by a valid variable name or by valid punctuation (${, $(). When that happens, the shell passes the $ sign literally, so grep again sees the regex d$. $ is only expanded when it is followed by a valid variable name (even if the variable is undefined — what matters is that a name follows, as in $PATH or $fioejsfoeij or single-character variables such as $- or $$), or in the constructs ${…}, $(…), $((…)) (also $[…] in bash and zsh, and more constructs in zsh).

The complete rules for shell expansion are far too complex to describe in a post or a dozen. In practice it's enough to remember the usual cases:

  • \ (backslash) quotes the next character unless it's a newline, and the backslash is always stripped;
  • '…' (single quotes) quotes every character except ' itself;
  • "…" (double quotes) quote every character except "$\`, and \ inside double quotes causes the following character to be interpreted literally and is only stripped if the next character was special.
share|improve this answer
    
Also note that e.g. "This and $that" expands the shell variable that (yes, it is implicit in the answer, but it is a snare for unvary newbies...) –  vonbrand Mar 1 '13 at 0:51
add comment

The \< is first escaped by the shell and its value becomes the literal < character. So the regular expression passed to grep is the string <H, which doesn't have a special meaning.

And if you need a deep knowledge of that particular relation you should consult Gilles' answer.

share|improve this answer
1  
Also can have some extra fun with \\\<H... –  vonbrand Mar 1 '13 at 0:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.