Search for special characters using grep

file searchgrepsearchstring

I want to search for the lines that contains any of the following characters:

: / / ? # [ ] @ ! $ & ' ( ) * + , ; = %

Best Answer

grep "[]:/?#@\!\$&'()*+,;=%[]"

Within a bracketed expression, [...], very few character are "special" (only a very small subset, like ], - and ^, and the three combinations [=, [: and [.). When including ] in [...], the ] must come first (possibly after a ^). I opted to put the ] first and the [ last for symmetry.

The only other thing to remember is that a single quoted string can not include a single quote, so we use double quotes around the expression. Since we use a double quoted string, the shell will poke around in it for things to expand. For this reason, we escape the $ as \$ which will make the shell give a literal $ to grep, and we escape ! as \! too as it's a history expansion in bash (only in interactive bash shells though).

Would you want to include a backslash in the set, you would have to escape it as \\ so that the shell gives a single backslash to grep. Also, if you want to include a backtick `, it too must be escaped as \` as it starts a command substitution otherwise.

The command above would extract any line that contained at least one of the characters in the bracketed expression.


Using a single quoted string instead of a double quoted string, which gets around most of the annoyances with what characters the shell interprets:

grep '[]:/?#@!$&'"'"'()*+,;=%[]'

Here, the only thing to remember, apart from the placing of the ], is that a single quoted string can not include a single quote, so instead we use a concatenation of three strings:

  1. '[]:/?#@!$&'
  2. "'"
  3. '()*+,;=%[]'

Another approach would be to use the POSIX character class [[:punct:]]. This matches a single character from the set !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~, which is a larger set than what's given in the question (it additionally contains "-.<>^_`{|}~), but is all the "punctuation characters" that POSIX defines.

LC_ALL=C grep '[[:punct:]]'
Related Question