¿Cómo se pasa una variable que contiene barras como patrón sed
?
Por ejemplo, si tengo la siguiente variable:
var="/Users/Documents/name/file"
Quiero pasarlo a sed
como tal:
sed "s/$var/replace/g" "$file"
Sin embargo, obtengo errores. ¿Cómo puedo eludir el problema?
$var
Una respuesta pura de bash: use la expansión de parámetros para la barra invertida y escape de cualquier barra en la variable:
fuente
${parameter/pattern/string}
. Entonces, en este caso, el parámetro esvar
, el patrón es/\/
y la cadena es\\/
. Todas las instancias del patrón se reemplazan porque el patrón comienza con a/
.Otra forma de hacerlo, aunque más fea que la respuesta de anubhava, es escapando de todas las barras invertidas
var
usando otrosed
comando:entonces, esto funcionará:
fuente
El uso de
/
in sed como delimitador entrará en conflicto con las barras en la variable cuando se sustituya y, como resultado, obtendrá un error. Una forma de eludir esto es usar otro delimitador que sea exclusivo de cualquier carácter que esté en esa variable.puede utilizar el carácter octothorpe que se adapte a la ocasión (o cualquier otro carácter que no sea
/
para facilitar su uso)o
esto es adecuado cuando la variable no contiene espacios
o
Es más prudente usar lo anterior, ya que estamos interesados en sustituir lo que sea que esté en esa variable solo en comparación con las comillas dobles del comando completo, lo que puede hacer que su shell interpele cualquier carácter que pueda considerarse un carácter especial de shell en el shell.
fuente
$var
contiene~
, obviamente deberá elegir un delimitador diferente. El error "no terminado" parece que tu$var
contiene una nueva línea; es posible que pueda solucionarlo haciendo una barra invertida escapando de cada nueva línea en el valor, pero no creo que esto sea completamente portátil. En general, esto no está relacionado con el problema de las barras en el valor.sed -i "s~blah~$var~g" file
con comillas solo alrededor delsed
guión real .Esta es una pregunta antigua, pero ninguna de las respuestas aquí discute las operaciones más que
s/from/to/
con mucho detalle.La forma general de una
sed
declaración esdonde la dirección puede ser un rango de expresiones regulares o un rango de número de línea (o vacío, en cuyo caso la acción se aplica a cada línea de entrada). Así por ejemplo
eliminará las líneas 1 a 4 (la dirección es el rango del número de línea
1,4
y la acción es eld
comando de eliminación); yreemplazará la primera aparición de
foo
conbar
en cualquier línea entre la primera coincidencia en la expresión regularick
y el final del archivo (la dirección es el rango/ick/,$
y la acción es els
comando de sustitucións/foo/bar/
).En este contexto, si
ick
proviene de una variable, podría hacer(observe el uso de comillas dobles en lugar de simples, de modo que el shell pueda interpolar la variable, y la necesidad de citar el signo de dólar literal entre comillas dobles) pero si la variable contiene una barra, obtendrá un error de sintaxis. (El shell expande la variable, luego pasa la cadena resultante a
sed
; por lo tanto,sed
solo ve texto literal, no tiene el concepto de las variables del shell).La cura es usar un delimitador diferente (donde obviamente necesita poder usar un carácter que no puede ocurrir en el valor de la variable), pero a diferencia del
s%foo%bar%
caso, también necesita una barra invertida antes del delimitador si desea usar un carácter diferente delimitador que el predeterminado/
:(entre comillas simples, una barra invertida obviamente sería suficiente); o puede escapar por separado de cada barra en el valor. Esta sintaxis en particular es solo Bash:
o si usa un caparazón diferente, intente
Para mayor claridad, si
$variable
contiene la cadena1/2
, los comandos anteriores serían equivalentes aen el primer caso, y
en el segundo.
fuente
Utilice Perl, donde las variables son ciudadanos de primera clase, no solo macros en expansión:
-p
lee la entrada línea por línea e imprime la línea después del procesamiento\Q
cita todos los metacaracteres en la siguiente cadena (no es necesario para el valor presentado aquí, pero es necesario si el valor contiene[
o algunos otros valores especiales para expresiones regulares)fuente