Say it's very easy if I want to find something containing lower-case letters and numbers with

produce_text | grep -E '[0-9a-z]'

Brackets are useful to match a set of characters, but what about those that are somewhat special?
If I want to, using brackets, match any character but one of these: a closing bracket ], a dash (or hyphen) "-", both slashes / and \, a caret ^, a colon :.
Will it look like this (I know this doesn't work)?


2 Answers 2


To match a literal ] and a literal - in a Bracket Expression you'll have to use them like this:


or, even better, since some tools require the backslash to be escaped:


that is
The right-square-bracket ( ']' ) shall lose its special meaning and represent itself in a bracket expression if it occurs first in the list (after an initial '^', if any)
The hyphen-minus character shall be treated as itself if it occurs first (after an initial '^', if any) or last in the list
If a bracket expression specifies both '-' and ']', the ']' shall be placed first (after the '^', if any) and the '-' last within the bracket expression.
The rules for bracket expressions are the same for ERE and BRE.

  • 2
    I'd double the backslash to be on the safe side. It's needed with many awk implementations and perl for instance. Feb 5, 2017 at 1:58
  • What about "From caret to closing bracket"? Like [^-]] (This one fails)?
    – iBug
    Feb 6, 2017 at 23:02
  • 2
    @iBug - sure it fails as the right bracket has to be first if you want to match it literally. I'm not sure I get the point of that "range" that you mention as ^ is after ] so [^-]] would not work even if both ^ and ] were treated literally (just like [b-a]). Anyway, if you wanted to match from e.g. ; to closing bracket you could use a range up to the char before ] (which is backslash) and include ] as first char in the bracket expression so e.g. [];-\\]. Feb 6, 2017 at 23:41
  • @don_crissti What about [[.^.]-[.-.]]? I have a feeling that this would work. Let's assume that the ASCII code of ^ is before -.
    – iBug
    Feb 7, 2017 at 13:48
  • Got a lazy solution for my question. Simply get everything special to collating characters, like [^[.].][.-.]/\^:]
    – iBug
    Feb 7, 2017 at 13:55

Strangely perhaps, you need to have a couple of characters in specific places. You must have ] as the first character in a set, and - must be the last character in a set.

Here is an RE that meets your requirements: [^]\^/-]:

echo 'Hello[world]-[sun] ^^ 4/5 or 3\4' | grep -Eo '[^]\^/-]' | xargs
H e l l o [ w o r l d [ s u n 4 5 o r 3 4
  • 1
    It's not really strange, it's just necessary to avoid ambiguity
    – Kevin
    Feb 4, 2017 at 18:24
  • 1
    The second [ character doesn't belong there; the OP doesn't want to exclude it. Feb 5, 2017 at 1:53
  • @Scott well spotted, thank you. Answer updated. Feb 14, 2017 at 17:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .