Recentemente, tive problemas com algumas expressões regulares na linha de comando e descobri que, para combinar uma barra invertida, diferentes números de caracteres podem ser usados. Esse número depende da citação usada para o regex (nenhum, aspas simples, aspas duplas). Veja a seguinte sessão do bash para entender o que quero dizer:
echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file
Isso significa que:
- sem aspas, posso combinar uma barra invertida com 4-7 barras invertidas reais
- com aspas duplas, posso combinar uma barra invertida com 3-6 barras invertidas reais
- Com aspas simples, posso combinar uma barra invertida com 2-3 barras invertidas reais
Entendo que uma barra invertida extra é ignorada pelo shell (na página de manual do bash):
"Uma barra invertida não citada (\) é o caractere de escape. Ele preserva o valor literal do próximo caractere a seguir"
Isso não se aplica aos exemplos de aspas simples, porque nenhuma fuga é feita entre aspas simples.
E uma barra invertida adicional é ignorada pelo comando grep ("\ c" é apenas "c" escapado, mas é o mesmo que "c", porque "c" não tem um significado especial em uma regex).
Isso explica o comportamento do exemplo com aspas simples, mas eu realmente não entendo os outros dois exemplos, especialmente porque há uma diferença entre seqüências de caracteres entre aspas e aspas duplas.
Novamente, uma citação da página de manual do bash:
"A inclusão de caracteres entre aspas duplas preserva o valor literal de todos os caracteres dentro das aspas, com exceção de $,`, \ e, quando a expansão do histórico estiver ativada,!. "
Eu tentei o mesmo com o GNU awk (por exemplo awk /ab\cd/{print} file
), com os mesmos resultados.
Perl, no entanto, mostra resultados diferentes (usando, por exemplo perl -ne
"/ab\\cd/"\&\&print file
):
- sem aspas, posso combinar uma barra invertida com 4-5 barras invertidas reais
- com aspas duplas, posso combinar uma barra invertida com 3-4 barras invertidas reais
- Com aspas simples, posso combinar uma barra invertida com duas barras invertidas reais
Alguém pode explicar essa diferença entre as seqüências de caracteres regex não citadas e duplas na linha de comando para grep e awk? Eu não estou tão interessado em uma explicação do comportamento de Perl, já que geralmente não uso uma linha do Perl.
printf "\ntest"
inserirá uma nova linha antes de "teste", mesmo que"\n"
deva ter sido traduzida para"n"
o shell como está entre aspas duplas ... (então o resultado esperado deve ser, por "\ ntest", "ntest". Deveríamos ter o hábito de escrever:printf "\\ntest"
orprintf '\ntest'
, mas de alguma forma eu vejo muitos scripts confiando na estranheza.