2009-04-18 29 views
5

Estoy escribiendo una secuencia de comandos de shell y quiero escapar de una cadena. ¿Hay alguna manera de convertir esto:Escape de una cadena

I'm happy. 
You're sad. 

a

I\'m happy.\nYou\'re sad. 

estoy bastante seguro de que hay alguna combinación de sed/awk que hace esto ....

Gracias

Respuesta

0

intente

sed 's/\\ /\\n/g' | sed 's/\\'/\\\'/g' 

Probablemente arruiné algunos \ aquí. La mejor manera es probarlo usted mismo.

+0

Usted no tiene que ejecutar 2 comandos sed, puede ejecutar múltiples sustituciones dentro de comando sed. Creo que cada uno termina con un ";" carácter, aunque si eso no funciona, simplemente coloque las 2 líneas en un archivo y use "sed -f " – slacy

+0

@slacy: sed-e 's/foo/bar/g' -e 's/baz/qux/g ' –

+0

no lo sabía. ¡Gracias! – Chaitan

0

Esto funciona para reemplazar el ' con \'.

echo "I'm happy. You're sad" | sed "s/'/\\\'/g" 

¿Estás seguro que quieres reemplazar el espacio entre "feliz". y "You're" con un \n? \n es una nueva línea, pero su línea original no parece tener una nueva línea allí.

+0

Sí, él quiere \ n, él simplemente echó a perder su marcado SO (Eddie lo arregló) – derobert

0

Creo que esto hace lo que está buscando. La secuencia de las operaciones en el comando sed es bastante crítica. Tenga en cuenta que esto también se ocupa de las barras invertidas (así como las comillas simples) en la cadena (mi pronta PS1 es Osiris JL:):

Osiris JL: cat zzz 
xxx="I'm happy. 
You're sad." 
yyy=$(echo "$xxx" | sed 's/[\'\'']/\\&/g;s/$/\\n/;$s/\\n$//') 
echo "$xxx" 
echo $xxx 
echo "$yyy" 
echo $yyy 
#eval echo $yyy 
#eval echo "$yyy" 
Osiris JL: sh zzz 
I'm happy. 
You're sad. 
I'm happy. You're sad. 
I\'m happy.\n 
You\'re sad. 
I\'m happy.\n You\'re sad. 
Osiris JL: 
0

Aquí está mi solución con awk:

$ awk '{$1=$1}1' FS=\' OFS="\\\'" ORS='\\n' <<< "I'm happy. 
You're sad." 

Esto da lugar a la salida

I\'m happy.\nYou\'re sad.\n 

Explicación:

puse el separador de campo (FS) para ' (escapar de ella para la shell como \') y la salida Separador de campo (OFS) para \' (envuelto en "..." para escapar de la ' para la shell y escapar de la \ dos veces , una vez para shell y una segunda vez para awk, como "\\\'"). Sin más opciones, el separador de registro (RS) es el carácter de nueva línea, pero establece la salida separador de registros (ORS) a \n (otra vez escapar de la \ para awk como \\n).

Ahora lo único que queda para contar awk que hacer es volver a calcular cada registro (mediante el establecimiento de $1 a $1, nada cambia, pero awk piensa que el registro modificado, sustituyendo efectivamente FS por OFS und así cada ' por \') e imprima cada registro (esto es lo que hace el patrón 1: 1 es verdadero para todos los registros y dado que no se realizó ninguna acción, se ejecuta la acción estándar {print $0}), sustituyendo efectivamente RS por ORS y por lo tanto cada nueva línea por \n.

1

Puede usar llano simple para eso (vea http://tldp.org/LDP/abs/html/string-manipulation.html).

Algo así como:

#!/bin/bash 
X="I'm happy. 
You're sad." 
echo "========== BEFORE ==========" 
echo "${X}" 
echo "========== AFTER ===========" 
X="${X//\'/\\\'}" 
X="${X//$'\n'/\\n}" 
echo "${X}" 
echo "============================" 

producirá una salida:

========== BEFORE ========== 
I'm happy. You're sad. 
========== AFTER =========== 
I\'m happy.\nYou\'re sad. 
============================ 
+0

¿Utiliza bash u otra alternativa (como por ejemplo "dash" en las distribuciones de Ubuntu)? Compruebe ejecutando: #> ls -la/bin/bash si se trata de un enlace simbólico, probablemente NO esté utilizando BASH. –

+0

Eso fue solo una muestra, lo que evitó lanzar procesos separados en una subcapa, como lo muestran la mayoría de las soluciones propuestas. He modificado el código de muestra para hacer lo que se solicita en el encabezado del tema. Ahora lo hace. –

+0

Ahora funciona para mí también. Eliminaré mis comentarios anteriores ya que no agregan nada más que confusión al guion actual. – mschilli

Cuestiones relacionadas