
Я заменяю строку другой строкой, которая включает экранированные кавычки:
echo "replace FOO" | sed -e "s~FOO~test\\\"test~g"
Я ожидал увидеть replace test\"test
. Вместо этого я вижу replace test"test
.
Как мне sed
включить мою последовательность побега?
решение1
Обратная косая черта является экранирующим символом как в двойных кавычках, так и в sed
замене. Так что с "\\\""
, sed видит, \"
что нужно, чтобы иметь в виду"
Попробуйте использовать одинарные кавычки:
echo "replace FOO" | sed -e 's~FOO~test\\"test~g'
или дважды побег:
echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"
решение2
An \
является особенным как для оболочки (которая удаляет одно), так и для sed (который удаляет другое). Чтобы sed понял, что на самом деле нужно, вам нужно передать sed следующую строку:
s~FOO~test\\\"test~g
Который sed преобразует в test\"test
, что вам и нужно.
Затем оболочка должна получить либо строку в двойных кавычках, где каждый символ \
удвоен и "
заключен в кавычки \"
(то есть 7 \
):
sed "s~FOO~test\\\\\\\"test~g"
Который будет преобразован оболочкой в "s~FOO~test\\"test~g" и sed будет использовать s~FOO~test\"test~g
.
Или, что немного проще, используйте одинарные кавычки '
(всего 3 \
):
sed 's~FOO~test\\\"test~g'
Добавлен
В комментариях вы написали: «На самом деле я заменяю внутренний текст переменной окружения» и «К сожалению, моя переменная содержит двойные и одинарные кавычки»
Ну, тогда задайте вашей переменной именно то значение, которое вы хотите, чтобы получил sed, например:
$ var='test\'\''test\"test'; echo "$var"
test\'test\"test
А если слеш используется только для экранирования кавычек, измените переменную следующим образом (предполагая, что это bash, для создания переносимого решения потребуется больше работы):
$ echo "${var//\\/\\\\\\}"
test\\\'test\\\"test
Который преобразует единицу \
(записывается как \\
) втри \
(пишется как \\\\\\
).
И замена будет работать следующим образом:
$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'
Этонетобщее решение для любого \
в переменной.
Общее решение
Общее решение потребует двух проходов, чтобы удвоить все \
, а затем экранировать каждую двойную кавычку:
$ var='test\'\''test\"test aa\\\"bb\\\\\'\''cc\'\'
$ echo "$var"
test\'test\"test aa\\\"bb\\\\\'cc\'
Затем измените var
:
$ var=${var//\\/\\\\}; var=${var//\"/\\\"}; echo "$var"
test\\'test\\\"test aa\\\\\\\"bb\\\\\\\\\\'cc\\'
И замена будет работать так:
$ echo "replace FOO" | sed -e 's~FOO~'"$var"'~g'
replace test\'test\"test aa\\\"bb\\\\\'cc\'
Точное исходное содержимое переменной var
.