Recientemente tuve problemas con algunas expresiones regulares en la línea de comandos, y descubrí que para hacer coincidir una barra invertida, se pueden usar diferentes números de caracteres. Este número depende de la cita utilizada para la expresión regular (ninguna, comillas simples, comillas dobles). Vea la siguiente sesión de bash para lo que quiero decir:
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
Esto significa que:
- sin comillas, puedo hacer coincidir una barra invertida con 4-7 barras invertidas reales
- con comillas dobles, puedo hacer coincidir una barra invertida con 3-6 barras invertidas reales
- Con comillas simples, puedo hacer coincidir una barra invertida con 2-3 barras invertidas reales
Entiendo que el shell ignora una barra invertida adicional (desde la página de manual de bash):
"Una barra invertida no citada (\) es el carácter de escape. Conserva el valor literal del siguiente carácter que sigue"
Esto no se aplica a los ejemplos con comillas simples, porque no se realiza ningún escape entre comillas simples.
Y el comando grep ignora una barra invertida adicional ("\ c" es simplemente "c" escapado, pero esto es lo mismo que "c", porque "c" no tiene un significado especial en una expresión regular).
Esto explica el comportamiento del ejemplo con comillas simples, pero en realidad no entiendo los otros dos ejemplos, especialmente por qué hay una diferencia entre cadenas sin comillas y comillas dobles.
Una vez más, una cita de la página de manual de bash:
"El encerrar caracteres entre comillas dobles conserva el valor literal de todos los caracteres dentro de las comillas, con la excepción de $,`, \ y, cuando la expansión del historial está habilitada,! ".
Intenté lo mismo con GNU awk (por ejemplo awk /ab\cd/{print} file
), con los mismos resultados.
Perl, sin embargo, muestra resultados diferentes (usando, por ejemplo perl -ne
"/ab\\cd/"\&\&print file
):
- sin comillas, puedo hacer coincidir una barra invertida con 4-5 barras invertidas reales
- con comillas dobles, puedo hacer coincidir una barra invertida con 3-4 barras invertidas reales
- Con comillas simples, puedo combinar una barra invertida con 2 barras invertidas reales
¿Alguien puede explicar esa diferencia entre las cadenas de expresiones regulares no citadas y de doble letra en la línea de comandos para grep y awk? No estoy tan interesado en una explicación del comportamiento de Perl, ya que generalmente no uso las frases de Perl.
printf "\ntest"
insertará una nueva línea antes de "prueba", aunque"\n"
debería haber sido traducida"n"
por el shell como está dentro de comillas dobles ... (entonces el resultado esperado debería ser, por "\ ntest", "ntest". Deberíamos tener el hábito de escribir:printf "\\ntest"
oprintf '\ntest'
, pero de alguna manera veo una gran cantidad de guiones que dependen de la rareza.