Agregado

Agregado

Estoy reemplazando una cadena con otra cadena que incluye comillas escapadas:

echo "replace FOO" | sed -e "s~FOO~test\\\"test~g"

Lo que esperaría es ver replace test\"test. En lugar de eso veo replace test"test.

¿Cómo puedo sedincluir mi secuencia de escape?

Respuesta1

La barra invertida es un carácter de escape tanto entre comillas dobles como en el sedreemplazo. Entonces con "\\\"", sed ve \"lo que significa"

Pruebe con comillas simples:

echo "replace FOO" | sed -e 's~FOO~test\\"test~g'

o escapar doblemente:

echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"

Respuesta2

An \es especial tanto para el shell (que elimina uno) como para sed (que elimina otro). Para que sed comprenda lo que realmente se necesita, debes darle a sed esta cadena:

s~FOO~test\\\"test~g

A qué sed se convertirá test\"test, que es lo que necesitas.

Luego, el shell debería recibir una cadena entre comillas dobles con cada \doble y "entre comillas \"(eso es 7 \):

sed "s~FOO~test\\\\\\\"test~g"

El cual será convertido por el shell a "s~FOO~test\\"test~g" y sed usará s~FOO~test\"test~g.

O, un poco más simple, use comillas simples '(solo 3 \):

sed 's~FOO~test\\\"test~g'

Agregado

En los comentarios dijiste: "De hecho, estoy reemplazando el texto interno con una variable de entorno" y "Desafortunadamente, mi variable contiene comillas simples y dobles".

Bueno, entonces, configura tu variable exactamente con lo que quieres que reciba sed, por ejemplo:

$ var='test\'\''test\"test'; echo "$var"
test\'test\"test

Y, si la barra diagonal solo se usa para escapar de la comilla, modifique la variable con esto (asumiendo bash, una solución portátil necesita más trabajo):

$ echo "${var//\\/\\\\\\}"
test\\\'test\\\"test

Lo que convertirá uno \(escrito como \\) entres \(Escrito como \\\\\\).

Y el reemplazo funcionará así:

$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'

Esto esnouna solución general para cualquiera \en la variable.

solución general

Una solución general necesitaría dos pases para duplicar todo \y luego escapar de cada comilla doble:

$ var='test\'\''test\"test    aa\\\"bb\\\\\'\''cc\'\'
$ echo "$var"
test\'test\"test    aa\\\"bb\\\\\'cc\'

Luego modifica var:

$ var=${var//\\/\\\\}; var=${var//\"/\\\"}; echo "$var"
test\\'test\\\"test    aa\\\\\\\"bb\\\\\\\\\\'cc\\'

Y el reemplazo funcionará así:

$ echo "replace FOO" | sed -e 's~FOO~'"$var"'~g'
replace test\'test\"test    aa\\\"bb\\\\\'cc\'

Exactamente el contenido original de la variable var.

información relacionada