
Ich ersetze eine Zeichenfolge durch eine andere Zeichenfolge, die maskierte Anführungszeichen enthält:
echo "replace FOO" | sed -e "s~FOO~test\\\"test~g"
Ich würde erwarten, dass angezeigt wird replace test\"test
. Stattdessen sehe ich replace test"test
.
Wie kann ich sed
meine Escape-Sequenz einbinden?
Antwort1
Der Backslash ist ein Escape-Zeichen sowohl innerhalb von Anführungszeichen als auch in der sed
Ersetzung. Mit "\\\""
sieht sed also, \"
was es bedeutet"
Versuchen Sie es mit einfachen Anführungszeichen:
echo "replace FOO" | sed -e 's~FOO~test\\"test~g'
oder doppeltes Escape:
echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"
Antwort2
Ein \
ist sowohl für die Shell (die eins entfernt) als auch für sed (das ein anderes entfernt) etwas Besonderes. Damit sed versteht, was tatsächlich benötigt wird, müssen Sie sed diese Zeichenfolge geben:
s~FOO~test\\\"test~g
Welches sed konvertiert in test\"test
, was Sie benötigen.
Dann sollte die Shell entweder einen String in doppelten Anführungszeichen erhalten, wobei jedes \
verdoppelte und das "
zweite Anführungszeichen gesetzt ist \"
(das ist 7 \
):
sed "s~FOO~test\\\\\\\"test~g"
Dies wird von der Shell in „s~FOO~test\\"test~g" umgewandelt und von sed verwendet s~FOO~test\"test~g
.
Oder, etwas einfacher, verwenden Sie einfache Anführungszeichen '
(nur 3 \
):
sed 's~FOO~test\\\"test~g'
Hinzugefügt
In Kommentaren sagten Sie: „Eigentlich ersetze ich den inneren Text durch eine Umgebungsvariable“ und „Leider enthält meine Variable doppelte und einfache Anführungszeichen.“
Stellen Sie dann Ihre Variable genau auf das ein, was sed empfangen soll, Beispiel:
$ var='test\'\''test\"test'; echo "$var"
test\'test\"test
Und wenn der Schrägstrich nur verwendet wird, um das Anführungszeichen zu maskieren, ändern Sie die Variable folgendermaßen (unter der Annahme von Bash ist für eine portable Lösung mehr Arbeit erforderlich):
$ echo "${var//\\/\\\\\\}"
test\\\'test\\\"test
Dadurch wird eins \
(geschrieben als \\
) indrei \
(geschrieben als \\\\\\
).
Und der Ersatz funktioniert folgendermaßen:
$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'
Das istnichteine allgemeine Lösung für alle \
in der Variablen.
Allgemeine Lösung
Eine allgemeine Lösung würde zwei Durchläufe erfordern, um alles zu verdoppeln \
und dann jedes Anführungszeichen zu escapen:
$ var='test\'\''test\"test aa\\\"bb\\\\\'\''cc\'\'
$ echo "$var"
test\'test\"test aa\\\"bb\\\\\'cc\'
Dann ändern var
:
$ var=${var//\\/\\\\}; var=${var//\"/\\\"}; echo "$var"
test\\'test\\\"test aa\\\\\\\"bb\\\\\\\\\\'cc\\'
Und der Ersatz funktioniert folgendermaßen:
$ echo "replace FOO" | sed -e 's~FOO~'"$var"'~g'
replace test\'test\"test aa\\\"bb\\\\\'cc\'
Genau der ursprüngliche Inhalt der Variable var
.