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 was under the impression that a caret symbol means "beginning of the line" with Extended POSIX regular expressions.

However, when I use it with grep it behaves unexpectedly.

#grep --version
GNU grep 2.5.4
...

I am using GNU grep 2.5.4 on Ubuntu 10.04 Lucid Lynx.

I echo out a line ' hello', then pipe it to a grep that searches for "zero-or-more white-space characters followed by the letter h":

#echo ' hello' | grep -E '[:space:]*h'
 hello

grep finds it ok.

If I add a caret to indicate that I only want the pattern to match "zero-or-more white-space characters followed by the letter h" "at the beginning of the string":

#echo ' hello' | grep -E '^[:space:]*h'
#

No matches are found. I would expect the string to have matched because it begins with white-space followed by h.

Why does this caret symbol prevent a match?

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

To find a space, you have to use [:space:] inside another pair of brackets, which will look like [[:space:]]. You probably meant to express grep -E '^[[:space:]]*h'

To explain why your current one fails:

As it stands, [:space:]*h includes a character class looking for any of the characters: :, s, p, a, c, and e which occur any number of times (including 0), followed by h. This matches your string just fine, but if you run grep -o, you'll find that you've only matched the h, not the space.

If you add a carat to the beginning, either one of those letters or h must be at the beginning of the string to match, but none are, so it does not match.

share|improve this answer
    
Aaahaa. This makes sense. –  JW01 Oct 28 '11 at 11:32
add comment

Looks like it assumes that [:space:] will only appear within a bracket expression (highlighted matches with *):

echo 'hello' | grep -E '^[:space:]*h'
*h*ello
echo 'hello' | grep -E '[^[:space:]]*h'
*h*ello
echo ' hello' | grep -E '^[[:space:]]*h'
* h*ello

This is explained by the following snippet from man grep (my highlighting):

Finally, certain named classes of characters are predefined within bracket expressions [...] Note that the brackets in these class names are part of the symbolic names, and must be included in addition to the brackets delimiting the bracket expression.

share|improve this answer
    
Yes. I think that's correct. I have just noticed the man "(Note that the brackets in these [predefined] class names are part of the symbolic names, and must be included in addition to the brackets delimiting the bracket expression.)" –  JW01 Oct 28 '11 at 11:05
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.