
Estou substituindo uma string por outra string que inclui aspas de escape:
echo "replace FOO" | sed -e "s~FOO~test\\\"test~g"
O que eu esperaria é ver replace test\"test
. Em vez disso eu vejo replace test"test
.
Como posso sed
incluir minha sequência de escape?
Responder1
A barra invertida é um caractere de escape tanto entre aspas duplas quanto na sed
substituição. Então, com "\\\""
, sed vê \"
o que significa"
Experimente aspas simples:
echo "replace FOO" | sed -e 's~FOO~test\\"test~g'
ou escapar duplamente:
echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"
Responder2
An \
é especial tanto para o shell (que remove um) quanto para sed (que remove outro. Para que o sed entenda o que é realmente necessário, você precisa fornecer ao sed esta string:
s~FOO~test\\\"test~g
Para qual sed será convertido test\"test
, é disso que você precisa.
Em seguida, o shell deve receber uma string entre aspas duplas com cada \
duplicado e "
entre aspas \"
(isso é 7 \
):
sed "s~FOO~test\\\\\\\"test~g"
Que será convertido pelo shell para "s~FOO~test\\"test~g" e sed usará s~FOO~test\"test~g
.
Ou, um pouco mais simples, use aspas simples '
(apenas 3 \
):
sed 's~FOO~test\\\"test~g'
Adicionado
Nos comentários você disse: "Na verdade, estou substituindo o texto interno por uma variável de ambiente" e "Infelizmente minha variável contém aspas duplas e simples"
Pois bem, defina sua variável exatamente para o que você deseja que o sed receba, exemplo:
$ var='test\'\''test\"test'; echo "$var"
test\'test\"test
E, se a barra for usada apenas para escapar da aspa, modifique a variável com isto (assumindo que o bash, uma solução portátil precisa de mais trabalho):
$ echo "${var//\\/\\\\\\}"
test\\\'test\\\"test
O que converterá um \
(escrito como \\
) paratrês \
(escrito como \\\\\\
).
E a substituição funcionará assim:
$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'
Isso énãouma solução geral para qualquer \
na variável.
Solução geral
Uma solução geral precisaria de duas passagens para dobrar tudo \
e depois escapar de cada aspas duplas:
$ var='test\'\''test\"test aa\\\"bb\\\\\'\''cc\'\'
$ echo "$var"
test\'test\"test aa\\\"bb\\\\\'cc\'
Então modifique var
:
$ var=${var//\\/\\\\}; var=${var//\"/\\\"}; echo "$var"
test\\'test\\\"test aa\\\\\\\"bb\\\\\\\\\\'cc\\'
E a substituição funcionará assim:
$ echo "replace FOO" | sed -e 's~FOO~'"$var"'~g'
replace test\'test\"test aa\\\"bb\\\\\'cc\'
Exatamente o conteúdo original da variável var
.