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.
fonte
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.Este link descreveu citações e fugas do bash
Sua pergunta lida com as três primeiras seções.
Abaixo está um gráfico de como as seqüências as
bash
transmitemgrep
e comogrep
as interpreta internamente.Vamos primeiro olhar
echo "#ab\\cd" > file
.No fraco entre aspas ("")
"#ab\\cd"
, o\\
é um escape\
que é passado parafile
um único literal\
. Então,file
contémab\cd
Agora, aos seus comandos: A tabela abaixo pode ajudar a ver o que realmente acontece a cada chamada. O
*
mostra os que correspondem ao conteúdo do arquivo. É realmente apenas uma questão de aplicar as regras de escape do bash, como na página da web, com particular atenção à resposta de daniel kullmann, onde ele se refere ao comportamento de escape em uma situação de citações fracas .fonte