Variable de entorno de sustitución en sed

Si ejecuto estos comandos desde un script:

#my.sh PWD=bla sed 's/xxx/'$PWD'/' ... $ ./my.sh xxx bla 

está bien.

Pero, si corro:

 #my.sh sed 's/xxx/'$PWD'/' ... $ ./my.sh $ sed: -e expression #1, char 8: Unknown option to `s' 

Leí en los tutoriales que para sustituir las variables de entorno del intérprete de comandos que necesita detener, y ‘citar’ la parte $varname para que no se sustituya directamente, que es lo que hice, y que funciona solo si la variable se define inmediatamente antes .

¿Cómo puedo obtener sed para reconocer un $var como una variable de entorno como se define en el shell?

Sus dos ejemplos son idénticos, lo que hace que los problemas sean difíciles de diagnosticar. Problemas potenciales:

  1. Es posible que necesite comillas dobles, como en sed 's/xxx/'"$PWD"'/'

  2. $PWD puede contener una barra inclinada, en cuyo caso debe encontrar un carácter no incluido en $PWD para usar como delimitador.

Para resolver ambos problemas a la vez, quizás

 sed 's@xxx@'"$PWD"'@' 

Además de la respuesta de Norman Ramsey, me gustaría añadir que puede citar dos veces toda la cadena (lo que puede hacer que la statement sea más legible y menos propensa a errores).

Por lo tanto, si desea buscar ‘foo’ y reemplazarlo con el contenido de $ BAR, puede encerrar el comando sed entre comillas dobles.

 sed 's/foo/$BAR/g' sed "s/foo/$BAR/g" 

En el primero, $ BAR no se expandirá correctamente, mientras que en el segundo $ BAR se expandirá correctamente.

Puede usar otros caracteres además de “/” en sustitución:

 sed "s#$1#$2#g" -i FILE 

Otra alternativa fácil:

Como $PWD generalmente contiene una barra inclinada / , use | en lugar de / para la statement sed:

 sed -e "s|xxx|$PWD|" 

Con la edición de su pregunta, veo su problema. Digamos que el directorio actual es /home/yourname … en este caso, su comando a continuación:

 sed 's/xxx/'$PWD'/' 

se expandirá a

 sed `s/xxx//home/yourname// 

que no es válido Debes poner un carácter \ delante de cada uno / en tu $ PWD si quieres hacer esto.

 VAR=8675309 echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\ sed 's/:[0-9]*:/:'$VAR':/1' 

donde VAR contiene lo que desea reemplazar el campo con

En realidad, lo más simple (al menos en gnu sed) es usar un separador diferente para el comando de sustitución sed (s). Entonces, en lugar de s / pattern / ‘$ mypath’ / expandido a s / pattern // my / path / que por supuesto confundirá el comando s, use s! Pattern! ‘$ Mypath’! que se ampliará a s! pattern! / my / path! He usado el carácter bang (!) (O uso lo que quieras) que evita la barra inclinada usual, pero por ningún medio, tu única opción como el separador.

mala forma: cambiar el delimitador

 sed 's/xxx/'"$PWD"'/' sed 's:xxx:'"$PWD"':' sed 's@xxx@'"$PWD"'@' 

tal vez esa no sea la respuesta final,

no se puede saber qué carácter ocurrirá en $PWD , / : OR @ .

la buena manera es reemplazar el personaje especial en $PWD .

buena forma: delimitador de escape

por ejemplo:

uso / como delimitador

 echo ${url//\//\\/} x.com:80\/aa\/bb\/aa.js echo ${url//\//\/} https://stackoverflow.com/questions/584894/environment-variable-substitution-in-sed/x.com:80/aa/bb/aa.js echo "${url//\//\/}" x.com:80\/aa\/bb\/aa.js echo $tmp | sed "s/URL/${url//\//\\/}/" URL echo $tmp | sed "s/URL/${url//\//\/}/" URL 

O

uso : como delimitador (más legible que / )

 echo ${url//:/\:} https://stackoverflow.com/questions/584894/environment-variable-substitution-in-sed/x.com:80/aa/bb/aa.js echo "${url//:/\:}" x.com\:80/aa/bb/aa.js echo $tmp | sed "s:URL:${url//:/\:}:g" https://stackoverflow.com/questions/584894/environment-variable-substitution-in-sed/x.com:80/aa/bb/aa.js 

Tratando con VARIABLES dentro de sed

 [root@gislab00207 ldom]# echo domainname: None > /tmp/1.txt [root@gislab00207 ldom]# cat /tmp/1.txt domainname: None [root@gislab00207 ldom]# echo ${DOMAIN_NAME} dcsw-79-98vm.us.oracle.com [root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: ${DOMAIN_NAME}/g' --- Below is the result -- very funny. domainname: ${DOMAIN_NAME} --- You need to single quote your variable like this ... [root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: '${DOMAIN_NAME}'/g' --- The right result is below domainname: dcsw-79-98vm.us.oracle.com 

Tuve un problema similar, tenía una lista y tengo que crear un script SQL basado en la plantilla (que contenía @INPUT@ como elemento para reemplazar):

 for i in LIST do awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output done