Um zu entkommen Variablen auf der linken Seite und die rechte Seite eines zu verwendenden sBefehls in sed(hier $lhsund $rhsrespectively), dann würden Sie tun:
escaped_lhs=$(printf '%s\n' "$lhs" | sed 's:[][\/.^$*]:\\&:g')
escaped_rhs=$(printf '%s\n' "$rhs" | sed 's:[\/&]:\\&:g;$!s/$/\\/')
sed "s/$escaped_lhs/$escaped_rhs/"
Beachten Sie, dass $lhskein Newline-Zeichen enthalten sein darf.
Dies bedeutet, dass in der LHS alle regulären Ausdrücke ( ][.^$*), das Escaping-Zeichen selbst ( \) und das Trennzeichen ( /) maskiert werden .
Auf dem RHS müssen Sie nur &das Trennzeichen, den Backslash und das Newline-Zeichen (was Sie tun, indem Sie am Ende jeder Zeile einen Backslash einfügen, mit Ausnahme des letzten ( $!s/$/\\/)).
Dies setzt voraus, dass Sie /in Ihren sed sBefehlen als Trennzeichen verwenden und Extended REs nicht mit -r(GNU sed/ ssed/ ast/ busybox sed) oder -E(BSDs, astRecent GNU, Recent Busy Box) oder PCREs mit -R( ssed) oder Augmented REs mit -A/ -X( ast) aktivieren Alle haben zusätzliche RE-Operatoren.
Einige Grundregeln beim Umgang mit beliebigen Daten:
- Nicht verwenden
echo
- Zitieren Sie Ihre Variablen
- Berücksichtigen Sie die Auswirkung des Gebietsschemas (insbesondere seines Zeichensatzes: Es ist wichtig, dass die Escaping-
sed Befehle in demselben Gebietsschema wie der sedBefehl ausgeführt werden, z. B. mit den Escaped- Zeichenfolgen (und mit demselben sedBefehl).
- Vergessen Sie nicht das Newline-Zeichen (hier können Sie überprüfen, ob es
$lhsvorhanden ist, und Maßnahmen ergreifen).
Eine weitere Möglichkeit ist die Verwendung perlstatt sedund übergeben Sie die Zeichenfolge in der Umgebung und die Verwendung \Q/ \E perlregexp Operatoren für Strings wörtlich nehmen:
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl(Standardmäßig) wird vom Zeichensatz des Gebietsschemas nicht beeinflusst, da oben nur die Zeichenfolgen als Bytearrays betrachtet werden, ohne darauf zu achten, welche Zeichen (falls vorhanden) sie für den Benutzer darstellen. Mit sedkönnen Sie dasselbe erreichen, indem Sie das Gebietsschema für alle Befehle auf Cmit festlegen (dies wirkt sich jedoch auch auf die Sprache der etwaigen Fehlermeldungen aus).LC_ALL=Csed