
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 sed
incluir mi secuencia de escape?
Respuesta1
La barra invertida es un carácter de escape tanto entre comillas dobles como en el sed
reemplazo. 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
.