En el terminal de Ubuntu 18.04 LTS, cuando escribo este comando:
echo -e "Hello\\\n"
Da esto como la salida:
Hello\n
Pero debería imprimirse, como dice la página del manual :
Hello\
Es decir, primero imprimir Hello
, luego \
, luego un carácter de nueva línea (y luego otra nueva línea). ¿Dónde está el problema?
Vea estos pocos echo -e
comandos y su salida :
man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n
command-line
echo
yolin00
fuente
fuente
echo
en primer lugar: usarprintf
.Respuestas:
Las barras invertidas son tratadas especialmente por
echo -e
, pero primero a veces son tratadas especialmente por el shell (que en este caso esbash
), de acuerdo con las reglas de cotización del shell .El argumento
echo
realmente ve esHello\\n
. Debido a que ha pasado-e
aecho
, trata especialmente los escapes de barra invertida y\\
se contrae en uno solo\
. La finaln
no se escapa, por lo que aparece literalmente.La razón de esto es que, antes y por separado de la operación de
echo
sí mismo, el shell trata\
especialmente en algunos contextos pero no en otros. Los\
caracteres sin comillas siempre se tratan especialmente, las comillas simples\
nunca se tratan especialmente, pero el tratamiento de los\
caracteres con comillas dobles , como en el comando que ejecutó, es más sutil y complicado.Cuando el shell encuentra texto entre comillas dobles en un comando, como con
"Hello\\\n"
, trata\
como un carácter de escape cuando precede a un carácter que puede tener un significado especial dentro de comillas dobles y no de otra manera .\
veces tiene un significado especial en el interior""
, un\
que precede inmediatamente a otro\
tiene el efecto de citar ese segundo\
. Entonces, dentro de las comillas dobles, las primeras\\
se contraen\
.\
caracteres, hay un tercer\
personaje que no se ve afectado por esos dos primeros y que precede a unn
. Peron
no es un personaje que alguna vez se trata especialmente entre comillas dobles, por lo que\
antes no se trata especialmente en esta situación. Así se\n
queda\n
.El efecto es que, entre comillas dobles,
\\\n
se interpreta como\\n
.Cuando
echo -e
ve\\n
, el primero\
elimina el significado especial del segundo, por lo queecho
imprime\n
literalmente para ese texto.Si su objetivo es imprimir
Hello
con una nueva línea adicional pero sin barras invertidas (la pregunta era originalmente ambigua sobre esto, además creo que es un ejemplo útil), entonces una solución es eliminar a\
. Ejecución deecho -e "Hello\\n"
salidasHello
con una nueva línea adicional al final.Una mejor solución es usar comillas simples y escribir
echo -e 'Hello\n'
. Las comillas simples son la forma más fuerte de citar. Por lo general, una solución aún mejor es usar enprintf
lugar deecho
, lo que en este caso seríaprintf 'Hello\n\n'
.Si su objetivo es imprimir,
Hello\
incluida la barra diagonal inversa, seguida de una nueva línea adicional , entonces el enfoque con comillas dobles es posible pero engorroso. Para averiguarlo, al revés de trabajo:echo -e
convertidos\\
a\
y\n
a una nueva línea, y los convertidos de doble citando\\
a\
, para que pueda hacerlo con seis barras invertidas (echo -e "Hello\\\\\\n"
), ya que\\n
se convierte en\n
debido a una barra invertida de escape otra. También puede hacerlo con cinco, porque las comillas dobles se conservan\n
cuando\
no se escapa.Esto ilustra el beneficio de
echo -e
las comillas simples: simplemente ponga lo que quiera ver dentro de las comillas simples (echo -e 'Hello\\\n'
).printf
También es bueno aquí. Una opción esprintf 'Hello\\\n\n'
. Pero lo queprintf
realmente brilla es que puedes conectar argumentos adicionales. Puede usarprintf '%s\n\n' 'Hello\'
, que inserta el segundo argumento (literalmenteHello\
porque las comillas simples no cambian nada) en lugar de%s
.fuente