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.
fuente
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.Este enlace describe las citas de Bash y Escaping
Su pregunta trata sobre las primeras tres secciones.
A continuación se muestra una tabla de cómo las cadenas
bash
pasangrep
y cómogrep
las interpreta internamente.Veamos primero
echo "#ab\\cd" > file
.En las comillas débiles ("")
"#ab\\cd"
, se\\
trata de un escape\
que se pasafile
como un único literal\
. Entonces,file
contieneab\cd
Ahora, a sus comandos: El cuadro a continuación puede ayudar a ver qué sucede realmente con cada llamada. La
*
muestra los que coinciden con el contenido del archivo. Realmente es solo una cuestión de aplicar las reglas de escape de bash, como en la página web, con especial atención a la respuesta de daniel kullmann donde se refiere al comportamiento de escape en una situación de citas débiles .fuente