Para escapar de las variables que se utilizarán en el lado izquierdo y en el lado derecho de un scomando en sed(aquí $lhsy $rhsrespectivamente), debe hacer lo siguiente:
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/"
Tenga en cuenta que $lhsno puede contener un carácter de nueva línea.
Es decir, en el LHS, escapa de todos los operadores regexp ( ][.^$*), el propio carácter de escape ( \) y el separador ( /).
En el RHS, solo necesita escapar &, el separador, la barra diagonal inversa y el carácter de nueva línea (lo que hace insertando una barra diagonal inversa al final de cada línea excepto la última ( $!s/$/\\/)).
Eso supone que lo usa /como separador en sus sed scomandos y que no habilita los RE extendidos con -r(GNU sed/ ssed/ ast/ busybox sed) o -E(BSD, astGNU reciente, busybox reciente) o PCRE con -R( ssed) o RE aumentados con -A/ -X( ast) que todos tienen operadores RE adicionales.
Algunas reglas básicas cuando se trata de datos arbitrarios:
- No usar
echo
- cita tus variables
- considere el impacto de la configuración regional (especialmente su conjunto de caracteres: es importante que los comandos de escape
sed se ejecuten en la misma configuración regional que el sedcomando usando las cadenas de escape (y con el mismo sedcomando) por ejemplo)
- no se olvide del carácter de nueva línea (aquí es posible que desee verificar si
$lhscontiene alguno y tomar medidas).
Otra opción es usar en perllugar de sedy pasar las cadenas en el entorno y usar los operadores \Q/ \E perlregexp para tomar cadenas literalmente:
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl(por defecto) no se verá afectado por el conjunto de caracteres de la configuración regional ya que, en lo anterior, solo considera las cadenas como matrices de bytes sin preocuparse por qué caracteres (si los hay) pueden representar para el usuario. Con sed, puede lograr lo mismo arreglando la configuración regional Ccon LC_ALL=Cpara todos los sedcomandos (aunque eso también afectará el idioma de los mensajes de error, si los hay).
sed, no necesitas escapar de ellas.find's-namees diferente de las expresiones regulares. Allí solo necesita escapar?,*barra invertida y[