在OS X上用sed和shell变量替换路径

时间:2016-01-23 22:01:48

标签: shell sed string-interpolation

我在Mac OS X上使用sed进行就地替换。

基本上我有这个:

#!/bin/sh -e
PREFIX="$1"

sed -i bak -e 's|OCAMLDIR|"${PREFIX}"|g' ocamloptrev

其中PREFIX是路径,因此我使用|

不幸的是,文件路径中的变量未按预期进行评估,我最终得到:

OCAMLC="${PREFIX}"/bin/ocamlopt

如何在${PREFIX}命令中正确评估sed

2 个答案:

答案 0 :(得分:7)

试试这个:

#!/bin/sh -e
PREFIX="$1"

sed -i bak -e 's|OCAMLDIR|'"${PREFIX}"'|g' ocamloptrev

你基本上做了什么,是"退出" /超出单引号字符串,输入双引号字符串,解释双引号内的变量,然后输入单引号再次。

通过这个简单的例子,我们也可以使用双引号,它允许解释变量:

#!/bin/sh -e
PREFIX="$1"

sed -i bak -e "s|OCAMLDIR|${PREFIX}|g" ocamloptrev

如果您尝试在单引号内使用双引号(""),则它们也不会被解释。 This part of the Bash manual更详细地解释了这一点。

  

3.1.2.2单引号

     

用单引号括起字符(''')会保留引号中每个字符的字面值。单引号之间可能不会出现单引号,即使前面有反斜杠也是如此。

     

3.1.2.3双引号

     

用双引号('"')括起字符会保留引号中所有字符的字面值,但$`\除外,并且,在启用历史记录扩展时,!。字符$`在双引号中保留其特殊含义(请参阅Shell Expansions)。 ...

答案 1 :(得分:3)

Shell变量不会在单引号内展开(单引号中没有元字符,甚至没有反斜杠),所以你需要使用类似这样的东西,在${PREFIX}周围用双引号确保空格等在值被正确处理:

sed -i bak -e 's|OCAMLDIR|'"${PREFIX}"'|g' ocamloptrev

或者您甚至可以使用:

sed -i bak -e "s|OCAMLDIR|${PREFIX}|g" ocamloptrev

后者是安全的,因为双引号内的材料不包含shell元字符(美元符号,反斜杠和反引号是主要的危险信号)。如果字符串的其余部分中存在狡猾的字符,则第一个版本使用起来更安全。

就个人而言,我使用.bak而非bak作为后缀。