我在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
?
答案 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
作为后缀。