Primeiro, observe que a barra simples corresponde muito:
$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
e.g.
No que diz respeito a Bash , um período de escape é o mesmo que um período. Bash passa o período para grep . Para grep, um período corresponde a qualquer coisa.
Agora, considere:
$ echo $'eegg \n e.g.' | grep e\.g\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\.g\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\.g\\.
$
Quando o Bash vê uma barra dupla, reduz-a a uma única barra e a passa para o grep que, no primeiro dos três testes acima, vê, como queremos, uma única barra antes de um ponto. Assim, isso faz a coisa certa.
Com uma barra tripla, o Bash reduz os dois primeiros para uma única barra. Em seguida, ele vê \.
. Como um período de escape não tem um significado especial para o Bash, isso é reduzido a um período simples. O resultado é que o grep vê, como queremos, uma barra antes de um período.
Com quatro barras, o Bash reduz cada par a uma única barra. Bash passa para grep duas barras e um ponto final. O grep vê as duas barras e um ponto e reduz as duas barras a uma única barra de texto literal . A menos que a entrada tenha uma barra literal seguida por qualquer caractere, não há correspondências.
Para ilustrar isso por último, lembre-se de que dentro de aspas simples, todos os caracteres são literais. Assim, dadas as três linhas de entrada a seguir, o comando grep corresponde apenas na linha com a barra literal na entrada:
$ echo 'eegg
e.g.
e\.g\.' | grep e\\.g\\.
e\.g\.
Resumo do comportamento de Bash
Para Bash, as regras são
-
Duas barras são reduzidas a uma única barra.
-
Uma barra na frente de um caractere normal, como um ponto, é apenas o caractere normal (ponto).
Assim:
$ echo \. \. \\. \\.
. \. \. \.
Existe uma maneira simples de evitar toda essa confusão: na linha de comando do Bash, expressões regulares devem ser colocadas entre aspas simples. Dentro daspas simples, Bash deixa tudo em paz.
$ echo '\. \. \\. \\.' # Note single-quotes
\. \. \\. \\.