Coder Perfect

In sed, you can change the environment variable.

Problem

If I run these commands from a script:

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

it is fine.

However, if I run:

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

To substitute environment variables from the shell, I read in tutorials that you must pause and ‘out quote’ the $varname section so that it is not substituted directly, which is what I did, and which only works if the variable is defined just before.

How can I get sed to identify a $var as a shell-defined environment variable?

Asked by RomanM

Solution #1

Your two samples appear to be identical, making it difficult to spot errors. Problems that could arise:

Perhaps it’s possible to solve both problems at the same time.

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

Answered by Norman Ramsey

Solution #2

In addition to Norman Ramsey’s response, I’d like to point out that the full string can be double-quoted (which may make the statement more readable and less error prone).

You can enclose the sed command in double-quotes if you wish to search for ‘foo’ and replace it with the content of $BAR.

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

$BAR will not expand correctly in the first case, but will expand correctly in the second.

Answered by Jeach

Solution #3

Another easy alternative:

Because $PWD generally contains a slash /, for the sed statement, use | instead of /:

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

Answered by Thales Ceolin

Solution #4

Other characters can be substituted in place of “/”:

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

Answered by Paulo Fidalgo

Solution #5

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

maybe those not the final answer,

It’s impossible to predict which character will appear in $PWD, /: OR @.

the good way is replace(escape) the special character in $PWD.

Try replacing URL with $url (has: / in content) as an example.

x.com:80/aa/bb/aa.js

in string $tmp

<a href="URL">URL</a>

in var escape / as / (before use in sed expression)

## step 1: try escape
echo ${url//\//\\/}
x.com:80\/aa\/bb\/aa.js   #escape fine

echo ${url//\//\/}
x.com:80/aa/bb/aa.js      #escape not success

echo "${url//\//\/}"
x.com:80\/aa\/bb\/aa.js   #escape fine, notice `"`


## step 2: do sed
echo $tmp | sed "s/URL/${url//\//\\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

echo $tmp | sed "s/URL/${url//\//\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

OR

in var (before use in sed expression) escape: as:

## step 1: try escape
echo ${url//:/\:}
x.com:80/aa/bb/aa.js     #escape not success

echo "${url//:/\:}"
x.com\:80/aa/bb/aa.js    #escape fine, notice `"`


## step 2: do sed
echo $tmp | sed "s:URL:${url//:/\:}:g"
<a href="x.com:80/aa/bb/aa.js">x.com:80/aa/bb/aa.js</a>

Answered by yurenchen

Post is based on https://stackoverflow.com/questions/584894/environment-variable-substitution-in-sed