¿Hay alguna forma de escapar de las comillas simples en el shell?

11

P.ej. quiero decir

perl -e 'print '"'"'Hello, world!'"'"', "\n";'

¿Hay alguna manera menos incómoda de hacerlo, por ejemplo, escapando de comillas simples?

Si, se que puedo escribir

perl -e 'print q[Hello, world!], "\n"'
perl -e 'print "Hello, world!\n"'

Pero esta pregunta se trata de citar en el shell, no en el Perl.

Estoy interesado en cómo hacerlo bashy cshen primer lugar.

codeholic
fuente

Respuestas:

9

Dennis señala las alternativas habituales en su respuesta (cadenas de comillas simples, dobles, dobles, simples concatenadas con comillas simples escapadas; usted ya mencionó los operadores de comillas personalizables de Perl), pero tal vez esta es la respuesta directa que estaba buscando. para.

En los shells tipo Bourne (sh, ksh, ash, dash, bash, zsh, etc.) las cadenas entre comillas simples son completamente literales. Esto facilita la inclusión de caracteres que, de lo contrario, el shell trataría especialmente sin tener que escapar de ellos, pero sí significa que el carácter de comillas simples en sí no puede incluirse en cadenas de comillas simples.

Incluso me niego a pensar en los shells de tipo csh ya que están completamente rotos en otros aspectos (ver Programación de Csh considerada perjudicial ).

Chris Johnsen
fuente
Gracias. "Esto es imposible", es la respuesta que esperaba :) Aunque siempre esperé que aquí haya documentos dedicados a desempeñar este papel.
codeholic
A diferencia de Perl, los documentos de shell tipo Bourne aquí solo son directamente útiles para proporcionar información a través de stdin. Por supuesto, puede poner comillas simples en ellos. También puede habilitar el "modo literal" de un documento aquí citando la palabra: (por ejemplo) blah <<\EOF … EOF. También puedes usar <<'EOF'y <<"EOF. Todos significan documentos literales aquí (a diferencia de Perl). Si realmente estuvieras decidido, podrías hacerlo blah "$(cat<<\EOF … EOF )" other args(usando nuevas líneas donde he escrito espacios en la sustitución de comandos; ksh y zsh pueden funcionar sin el gato , los demás lo necesitan). ¿Pero realmente valdría la pena?
Chris Johnsen
Solo quiero notar que las comillas simples zsh no son del todo literales. Zsh intentará interpretar una '\ U' en cualquier lugar de una cadena entre comillas simples como un código de caracteres, por ejemplo, echo '\U0000068\U000069'hace eco de 'hola'. No estoy seguro de por qué, a menos que sea un error en el shell.
Matthew
1
@Matthew: La interpretación de \Uen ese caso se realiza mediante el comando de eco incorporado (este comportamiento puede controlarse mediante -Ela opción BSD_ECHO y -e). Puede ver que la cadena literal se pasa (y no se interpreta de otra manera) en otros comandos; por ej printf %s\\n '\U0000068\U000069'.
Chris Johnsen
@ChrisJohnsen Gracias, soy nuevo en zsh y no me di cuenta de esto, pero tienes razón. La página de manual me dijo que -e es el valor predeterminado, pero zsh debe anular eso.
Mateo
5

Para mí, todos tus ejemplos producen:

¡Hola Mundo!

Y esto también:

perl -e 'print "Hello, world!", "\n";'

Y esto:

perl -e 'print '\''Hello, world!'\'', "\n";'

¿Puedes aclarar qué es lo que estás tratando de hacer?

En el shell, como Bash, si desea imprimir comillas como parte de la cadena, un tipo de comillas escapa al otro.

$ echo '"Hello, world!"'
"Hello, world!"
$ echo "'Hello, world!'"
'Hello, world!'

Editar:

Aquí hay otra forma:

$ perl -e 'print "\047Hello, world!\047", "\n";'
'Hello, world!'
$ echo -e "\047Hello, world! \047"
'Hello, world! '

El espacio después del signo de exclamación evita un error de expansión del historial. Podría haber hecho en su set +Hlugar.

Pausado hasta nuevo aviso.
fuente
1

No estoy seguro de si aparecería mi edición de la respuesta anterior:

Pegar lo mismo como una nueva respuesta:

Enfoque alternativo:

Cuando probé su solución, todavía no pude obtener el 'impreso.

Pero tomé el ejemplo de su solución e intenté lo siguiente:

$ perl -e '$foo = chr(39); print "${foo}Hello, world ${foo}", "\n";'
'Hello, world '

El valor ASCII de 'es 39.

Necesitaba esto para hacer una edición en línea a un montón de archivos para agregar 'en una ubicación de interés.

Kaushik B
fuente
1

Aquí el documento es la mejor manera de no preocuparse por escapar:

$ cat <<EOF
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

Puede inhibir completamente toda expansión utilizando el documento citado aquí:

$ cat <<'EOF'
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

Si desea pasarlo como argumento en lugar de entrada, puede usar xargs:

$ xargs -0 <<'EOF' perl -e
my $var = "Hello";
print $text, ', world!', "\n";'
EOF
Jérôme Pouiller
fuente
0

No sé si hay una opción para hacer esto en bash, pero con zsh puede usar ''después de activar la RC_QUOTESopción. (Recomendaría probar zsh; es principalmente compatible con bash y puede emular bash para una mayor compatibilidad).

Con bash (y aún la mayoría de las veces con zsh), solo lo uso '\''porque es más fácil de leer que '"'"'.

No tengo ni idea de cómo hacerlo en csh.

SilverWolf - Restablece a Monica
fuente
-1

Puede usar \ 'y \ "para escapar de las comillas con perl si se usa internamente como parte de un script perl. Sin embargo, no estoy seguro de si la línea de comando lo aceptará. Puede probarlo y ver si funciona.

Micah
fuente
3
Si fuera tan fácil, no preguntaría. Puedes probarlo y ver si funciona antes de publicar una respuesta.
codeholic