9

How do I escape a close-bracket character inside a character class? According to the manual, to match a literal ] it should be placed first in the list, but I need to match the complement of a class consisting of square bracket.

Most meta-characters lose their special meaning inside bracket expressions. To include a literal ] place it first in the list. Similarly, to include a literal ^ place it anywhere but first. Finally, to include a literal - place it last.

ealfonso
  • 5,383
  • 3
  • 31
  • 57

4 Answers4

11

How do I escape a close-bracket character inside a character class?

A ] is normally either the end of a POSIX character class, or it signals the end of the character class.

If a ] is the first character in the class (may follow an unescaped caret) it does not denote the end of the class and is evaluated as part of the set of characters that can be matched without escaping.

echo "foo [22-Jun-2014 04:11:37 UTC] bar" | grep -o '\[[^]]*\]'
# [22-Jun-2014 04:11:37 UTC]
hwnd
  • 65,661
  • 4
  • 77
  • 114
1

It depends on the implementation.

  • In grep -P mode, you can actually use [][] to match a char that is either an opening or closing bracket.
  • In general the syntax that is the most portable is to escape: [\]] and [\[]

Related

What does the “[^][]” regex mean?

Community
  • 1
  • 1
zx81
  • 38,175
  • 8
  • 76
  • 97
1

Unfortunately, zx81's solution did not work. In particular, for the input:

[22-Jun-2014 04:11:37 UTC]

grep -o '.[^[\]]*' 

fails.

What did work was not escaping the closing bracket at all:

grep '^[[][^]]*]'

It seems that grep still considers the closing bracket as first even if it is preceded by a caret.

ealfonso
  • 5,383
  • 3
  • 31
  • 57
0
user$ sleep 400 &
[1] 13242
user$ sleep 500 &
[2] 13253
user$ jobs
[1]-  Running                 sleep 400 &
[2]+  Running                 sleep 500 &
user$ jobs | grep "sleep 400" | grep -o ^"["[0-9][0-9]*"]"
[1]
user$ jobs | grep "sleep 500" | grep -o ^"["[0-9][0-9]*"]"
[2]

Why does this work?

The square brackets are treated as strings and without any explicit escape character, they are not the part of the grep regular expression special literals.

David Buck
  • 3,439
  • 29
  • 24
  • 31
Krishna Birla
  • 97
  • 1
  • 7