I need to grep for string containing special characters and make sure it is at the end of the line

For example, in list:

  • abc defg[h]ij
    I want to grep for defg[h]ij$

  • xyz 123*456
    I want to grep for 123*456$

The search string and possible match containing special characters are varying, thus a fixed masking is not possible.

I am looking for something like grep -F in combination with the end of line $ anchor. -w will not suffice, it must be end of line.


One approach is to escape those special characters before calling grep.

With zsh:

grep -e "${string//(#m)[[^.\\\$*]/\\$MATCH}\$" file

or POSIXly:

escaped_string=$(printf '%s\n' "$string" | sed 's/[[^.\$*]/\\&/g')
grep -e "$escaped_string\$" file

or supposing the $string doesn't contain \E, with GNU grep or pcregrep:

grep -Pe "\Q$string\E\$" file

or you could use awk like:

STRING="$string" awk 'BEGIN {s = ENVIRON["STRING"]; n = length(s)}
                      length >= n && substr($0, length - n + 1, n) == s'

or perl:

STRING="$string" perl -ne 'print if /\Q$ENV{"STRING"}\E$/'

(this time, perl knows that a \E found in $ENV{"STRING"} doesn't mark the end of the \Quoted string).

  • thx will use the posix approach but use: sed 's/[]\/$*.^|[]/\\&/g' to escape "]" as well some other
    – PeterK
    Nov 28 '14 at 10:33
  • @PeterK, no, if you turn | into \| then you make an ordinary character (| is not special for grep without -E) into a regexp operator with some grep implementation (\| is an alternation operator in GNU grep for instance). / is not special in any grep implementation. ] alone is not special either. Nov 29 '14 at 8:04

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.