Pour échapper les variables à utiliser à gauche et à droite d'une s
commande dans sed
(ici $lhs
et $rhs
respectivement), 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 $lhs
ne 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
s
commandes 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 sed
commande en utilisant les échappées des chaînes (et avec la même sed
commande) , par exemple)
- n'oubliez pas le caractère de nouvelle ligne (ici, vous voudrez peut-être vérifier s'il en
$lhs
contient et prendre des mesures).
Une autre option consiste à utiliser à la perl
place de sed
et à 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 à C
with LC_ALL=C
pour toutes les sed
commandes (bien que cela affecte également la langue des messages d'erreur, le cas échéant).