Em bash 3.2 ou superior e se a compatibilidade com 3.1 não estiver ativada (com a opção compat31 ou BASH_COMPAT=3.1 ), citando operadores de expressões regulares (não apenas com \ mas com qualquer um dos bash de operadores de cotação ( '...' , "..." , $'...' , $"..." )) remove seu significado especial.
[[ $var =~ 'OK$' ]]
corresponde apenas a strings que contêm OK$ literalmente (que $ corresponde a um literal $ )
[[ $var =~ OK$ ]]
corresponde a sequências que terminam em OK (que $ é o operador RE que corresponde ao final da sequência).
Isso também se aplica a regexps armazenados em variáveis ou o resultado de alguma substituição.
[[ $var =~ $regexp ]] # $var matches $regexp
[[ $var =~ "$string" ]] # $var contains $string
Note que pode tornar-se complicado porque existem alguns caracteres que você precisa citar para a sintaxe do shell (como espaços em branco, < , > , & , parênteses quando não correspondidos). Por exemplo, se você deseja corresponder à .{3} <> [)}]& regexp (3 caracteres seguidos por " <> " , ) ou } e & ), é necessário algo como:
[[ $var =~ .{3}" <> "[}\)]\& ]]
Se tiver dúvidas sobre quais caracteres precisam ser citados, você sempre pode usar uma variável temporária . Isso também significa que ele tornará o código compatível com bash31 , zsh ou ksh93 :
pattern='.{3} <> [})]&'
[[ $var =~ $pattern ]] # remember *not* to quote $pattern here
Essa também é a única maneira (além de usar a opção compat31 (ou BASH_COMPAT=3.1 )) você pode fazer uso dos operadores estendidos não POSIX dos regexps do seu sistema.
Por exemplo, para que \< seja tratado como o limite de palavras que está em muitos mecanismos de expressão regular, você precisa:
pattern='\<word\>'
[[ $var =~ $pattern ]]
Fazendo:
[[ $var =~ \<word\> ]]
não funciona, pois bash trata esses \ como operadores de criação de shell e tira-os antes de passar <word> para a biblioteca regexp.
Note que é muito pior em ksh93 onde:
[[ $var =~ "x.*$" ]]
Por exemplo, corresponderá a whatever-xa* , mas não a whatever-xfoo . A citação acima remove o significado especial para * , mas não para . nem $ .
O comportamento zsh é mais simples: as cotações não alteram o significado dos operadores regexp (como em bash31), o que contribui para um comportamento mais previsível (também pode usar regexps PCRE em vez de ERE (com set -o rematchpcre ) ).
yash não tem uma construção [[...]] , mas seu [ builtin tem um operador =~ (também em zsh ). E, claro, [ sendo um comando normal, a cotação não pode afetar a maneira como os operadores regexp são interpretados.
Observe também que, estritamente falando, o $s não contém 3 linhas, mas 2 linhas completas seguidas por uma linha não terminada. Contém hello\nworld\nOK . Na expressão regular estendida OK$ , o operador $ corresponderia apenas ao final da string .
Em uma sequência de 3 linhas completas , como hello\nworld\nOK\n (que você não seria capaz de obter com a substituição de comandos, como tiras de substituição de comandos all caracteres), o $ corresponderia após o \n , portanto, OK$ não corresponderia a ele.
Com zsh -o pcrematch , no entanto, o $ corresponde ao final da string e à nova linha no final da string, se houver uma, pois ela não passa o PCRE_DOLLAR_ENDONLY para pcre_compile . Isso pode ser visto como uma má idéia, geralmente, variáveis em shells não contêm um caractere de nova linha, e quando eles geralmente querem que eles sejam considerados dados .