Pour échapper les variables à utiliser à gauche et à droite d'une scommande dans sed(ici $lhset $rhsrespectivement), vous devez:
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/"
Notez qu'il $lhsne peut pas contenir de caractère de nouvelle ligne.
Autrement dit, sur le LHS, échappez à tous les opérateurs regexp ( ][.^$*), au caractère d'échappement lui-même ( \) et au séparateur ( /).
Sur le RHS, il vous suffit d'échapper &, le séparateur, la barre oblique inverse et le caractère de nouvelle ligne (ce que vous faites en insérant une barre oblique inversée à la fin de chaque ligne, sauf la dernière ( $!s/$/\\/)).
Cela suppose que vous utilisez /comme séparateur dans vos sed scommandes et que vous n'activez pas les RE étendues avec -r(GNU sed/ ssed/ ast/ busybox sed) ou -E(BSD ,,ast GNU récent, boîte occupée récente) ou PCRE avec -R( ssed) ou RE augmentées avec -A/ -X( ast) qui tous ont des opérateurs RE supplémentaires.
Quelques règles de base lors du traitement de données arbitraires:
- Ne pas utiliser
echo
- citer vos variables
- considérer l'impact des paramètres régionaux (en particulier son jeu de caractères: il est important que l' échappement
sed commandes sont exécutées dans le même lieu que la sedcommande en utilisant les échappées des chaînes (et avec la même sedcommande) , par exemple)
- n'oubliez pas le caractère de nouvelle ligne (ici, vous voudrez peut-être vérifier s'il en
$lhscontient et prendre des mesures).
Une autre option consiste à utiliser à la perlplace de sedet à passer les chaînes dans l'environnement et à utiliser le \Q/\E perl opérateurs regexp pour prendre des chaînes littéralement:
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl(par défaut) ne sera pas affecté par le jeu de caractères des paramètres régionaux car, dans ce qui précède, il considère uniquement les chaînes comme des tableaux d'octets sans se soucier des caractères (le cas échéant) qu'ils peuvent représenter pour l'utilisateur. Avec sed, vous pouvez obtenir le même résultat en fixant les paramètres régionaux à Cwith LC_ALL=Cpour toutes les sedcommandes (bien que cela affecte également la langue des messages d'erreur, le cas échéant).