sed中的环境变量替换

时间:2009-02-25 06:10:31

标签: linux unix shell sed

如果我从脚本运行这些命令:

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

没关系。

但是,如果我跑:

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

我在教程中读到要替换你需要停止的shell中的环境变量,并且“引用”$varname部分以便它不能直接替换,这就是我所做的,并且只有在变量是在之前定义的。

如何让sed将$var识别为在shell中定义的环境变量?

10 个答案:

答案 0 :(得分:246)

您的两个示例看起来完全相同,这使问题难以诊断。潜在问题:

  1. 您可能需要双引号,如sed 's/xxx/'"$PWD"'/'

  2. $PWD可能包含斜杠,在这种情况下,您需要找到$PWD中包含的字符 not 以用作分隔符。

  3. 要立刻解决这两个问题,也许

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

答案 1 :(得分:85)

除了Norman Ramsey的回答之外,我还想补充一点,你可以对整个字符串进行双引号(这可能会使语句更具可读性,更不容易出错)。

因此,如果您要搜索“foo”并将其替换为$ BAR的内容,则可以将sed命令括在双引号中。

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

在第一个中,$ BAR将无法正确扩展,而第二个$ BAR将正确扩展。

答案 2 :(得分:54)

您可以使用“/”之外的其他字符代替:

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

答案 3 :(得分:40)

另一个简单的选择:

由于$PWD通常会包含斜杠/,因此请使用|代替/作为sed语句:

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

答案 4 :(得分:13)

通过编辑问题,我看到了您的问题。假设当前目录为/home/yourname ...在这种情况下,您的命令如下:

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

将扩展为

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

无效。如果你想这样做,你需要在你的$ PWD中的每个\前放一个/字符。

答案 5 :(得分:3)

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

其中VAR包含您要用

替换字段的内容

答案 6 :(得分:3)

坏方法:更改分隔符

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

也许那些不是最终答案,

您无法知道$PWD/ :@中会出现什么字符。

好方法是替换$PWD中的特殊字符。

好方法:逃避分隔符

例如:

使用/作为分隔符

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

使用:作为分隔符(比/更具可读性)

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>

答案 7 :(得分:2)

实际上,最简单的事情(至少在gnu sed中)是为sed substitution(s)命令使用不同的分隔符。因此,而不是s / pattern /'$ mypath'/被扩展为s / pattern // my / path /这当然会混淆s命令,请使用s!pattern!'$ mypath'!这将扩展为s!pattern!/ my / path!我已经使用了爆炸(!)字符(或使用你喜欢的任何东西),它避免了通常的,但绝不是你唯一选择的正斜杠作为分隔符。

答案 8 :(得分:1)

我有类似的问题,我有一个列表,我必须基于模板构建一个SQL脚本(包含@INPUT@作为要替换的元素):

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

答案 9 :(得分:1)

在sed中处理VARIABLES

[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