Environment variable substitution in sed

2019-01-02 15:09发布

If I run these commands from a script:

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

it is fine.

But, if I run:

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

I read in tutorials that to substitute environment variables from shell you need to stop, and 'out quote' the $varname part so that it is not substituted directly, which is what I did, and which works only if the variable is defined immediately before.

How can I get sed to recognize a $var as an environment variable as it is defined in the shell?

10条回答
爱死公子算了
2楼-- · 2019-01-02 15:41

bad way: change delimiter

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

maybe those not the final answer,

you can not known what character will occur in $PWD, / : OR @.

the good way is replace the special character in $PWD.

good way: escape delimiter

for example:

use / as delimiter

echo ${url//\//\\/}
x.com:80\/aa\/bb\/aa.js

echo ${url//\//\/}
x.com:80/aa/bb/aa.js

echo "${url//\//\/}"
x.com:80\/aa\/bb\/aa.js

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

use : as delimiter (more readable than /)

echo ${url//:/\:}
x.com:80/aa/bb/aa.js

echo "${url//:/\:}"
x.com\:80/aa/bb/aa.js

echo $tmp | sed "s:URL:${url//:/\:}:g"
<a href="x.com:80/aa/bb/aa.js">x.com:80/aa/bb/aa.js</a>
查看更多
余生请多指教
3楼-- · 2019-01-02 15:45
VAR=8675309
echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\
sed 's/:[0-9]*:/:'$VAR':/1' 

where VAR contains what you want to replace the field with

查看更多
零度萤火
4楼-- · 2019-01-02 15:45

Dealing with VARIABLES within 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
查看更多
查无此人
5楼-- · 2019-01-02 15:46

You can use other characters besides "/" in substitution:

sed "s#$1#$2#g" -i FILE
查看更多
栀子花@的思念
6楼-- · 2019-01-02 15:48

I had similar problem, I had a list and I have to build a SQL script based on template (that contained @INPUT@ as element to replace):

for i in LIST 
do
    awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output
done
查看更多
柔情千种
7楼-- · 2019-01-02 15:56

Actually, the simplest thing (in gnu sed at least) is to use a different separator for the sed substitution (s) command. So instead of s/pattern/'$mypath'/ being expanded to s/pattern//my/path/ which will of course confuse the s command, use s!pattern!'$mypath'! which will be expanded to s!pattern!/my/path! I've used the bang (!) character (or use anything you like) which avoids the usual, but-by-no-means-your-only-choice forward slash as the separator.

查看更多
登录 后发表回答