In the man page of grep, I see

The symbols \< and \> respectively match the empty string at the beginning and  
end of a word.  The symbol \b matches the  empty  string at  the  edge  of  a  word.

But I still can't figure out the difference. To me, \b is Perl's notation for word boundary, while \< is Vim's notation for the same purpose.
PS: English is not my native language. Pardon me if the difference is obvious to you.

  • I can't think of any useful usage of \< or \> where you can't substitute \b. Obviously you can use \< and \> to create patterns that don't match anything, but that's not much use! So in practice it looks like there is no difference. – Graeme Mar 27 '14 at 9:58
  • I have to disagree I will prove it :-) I'll edit my answer to add an example – Kiwy Mar 27 '14 at 10:09
  • \< predates vim (it was used in grep during the 1980s). – Thomas Dickey Apr 25 '16 at 1:01

\< matches the beginning of a word
\> matches the end of a word
\b matches both boundaries if at the end or at the beginning

The important thing about those special characters is that they match an empty string and not the word boundary itself. a word boundary being the contrary of the the set of character represented by \w equivalent of [_[:alnum:]] (letter a to Z, digits and _) in Posix notation.


Finally, Graeme find a very interesting example:

$ echo 'acegi   z' | grep -o '[acegi ]*\>' | cat -A
$ echo 'acegi   z' | grep -o '[acegi ]*\b' | cat -A
acegi   $ 

Currently, this example shows that it can useful sometimes to match precisely the end of word instead of a word boundary because the use of matching space character is avoided by matching the end of word.
So in a more useful example, I would say that if you want to match non-word character and the end of this non-word, you can't use \>; but maybe \b can be used in this particular case because it will match the start of the next word.

So far no example manage to reach my mind. But in my opinion, there are probably some few use cases where it make sense, but my guess is that it's onlyfor readability purpose, Because when you put \b it's vague but if you precise start or end of the word then it gives a better understanding of the regexp to the persons who read it.

  • But can you think of a situation where it is useful to use \< or \> instead of \b? – Graeme Mar 27 '14 at 10:04
  • 1
    @Graeme: \<..\> would search for 2-letter words. – Stéphane Chazelas Mar 27 '14 at 10:08
  • @StephaneChazelas Ok, I see, so anything that matches a space or a word character can leave it ambiguous as to whether you are at the beginning or end of a word. – Graeme Mar 27 '14 at 10:20
  • 1
    Note those are transitions from word to non-word characters, they have nothing to do with spaces (which is just one of many non-word characters). – Stéphane Chazelas Mar 27 '14 at 10:26
  • Note that for three letter words, you'd have to write it \<\w{3}\> anyway, and that would be the same as \b\w{3}\b – Stéphane Chazelas Mar 27 '14 at 10:27

To answer the question on your title?

What's the difference between \b and \< ...

Almost none. Both match the boundary, the transition between a word and a non-word.

The only technical difference is:

  • The \b match the boundary on both start and end of a word.
  • The \< only match the start of a word.
  • The `>' only match the end of a word.

The practical difference is:

$ echo ',,abc...' | grep -o '[abc.,]*'
,,abc...                                   # match the whole string

$ echo ',,abc...' | grep -o '[abc.,]*\b'
,,abc                                      # to the rightmost (due to *) word boundary.

$ echo ',,abc...' | grep -o '[abc.,]*\>'
,,abc                                      # match to the same point (in this case).

$ echo ',,abc...' | grep -o '[abc.,]*\<'   
,,                                         # match to the rightmost **start** of a word.

The same could be done with spaces (cat added to reveal the spaces):

Up to the rightmost "word boundary" (any) (note the spaces):

$ echo 'abcd     abcd    Z' | grep -o '[a-z ]*\b' | cat -A
abcd     abcd    $

Up to the rightmost "word start" (same point):

$ echo 'abcd     abcd    Z' | grep -o '[a-z ]*\<' | cat -A
abcd     abcd    $

Up to the rightmost "word end" (no trailing space):

$ echo 'abcd     abcd    Z' | grep -o '[a-z ]*\>' | cat -A
abcd     abcd$

Or, with sed:

Four word boundaries:

$ echo "abc %-= def." | sed 's/\b/ |>X<| /g'
 |>X<| abc |>X<|  %-=  |>X<| def |>X<| .

Two start of word:

$ echo "abc %-= def." | sed 's/\</ |>X<| /g'
 |>X<| abc %-=  |>X<| def.

And two end of word:

$ echo "abc %-= def." | sed 's/\>/ |>X<| /g'
abc |>X<|  %-= def |>X<| .


From GNU info sed:

Matches a word boundary; that is it matches if the character to the left is a "word" character and the character to the right is a "non-word" character, or vice-versa.

     $ echo "abc %-= def." | sed 's/\b/X/g'
     XabcX %-= XdefX.


'\<' Matches the beginning of a word.

     $ echo "abc %-= def." | sed 's/\</X/g'
     Xabc %-= Xdef.


'>' Matches the end of a word.

     $ echo "abc %-= def." | sed 's/\>/X/g'
     abcX %-= defX.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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