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

Edg*_*ian 4 shell sed string-interpolation

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

基本上我有这个:

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

sed -i bak -e 's|OCAMLDIR|"${PREFIX}"|g' ocamloptrev
Run Code Online (Sandbox Code Playgroud)

PREFIX路径在哪里,因此我正在使用|.

不幸的是,文件路径中的变量没有像我预期的那样得到评估,我最终得到:

OCAMLC="${PREFIX}"/bin/ocamlopt
Run Code Online (Sandbox Code Playgroud)

如何才能${PREFIX}sed命令进行正确的评估?

Wil*_*ill 6

试试这个:

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

sed -i bak -e 's|OCAMLDIR|'"${PREFIX}"'|g' ocamloptrev
Run Code Online (Sandbox Code Playgroud)

你基本上是在做什么,是"退出" /单引号字符串之外获得,进入一个双引号字符串,解释双引号里面的变量,然后再次进入单引号.

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

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

sed -i bak -e "s|OCAMLDIR|${PREFIX}|g" ocamloptrev
Run Code Online (Sandbox Code Playgroud)

如果您尝试""在单引号内使用双引号(),则它们也不会被解释.Bash手册的这一部分更详细地解释了这一点.

3.1.2.2单引号

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

3.1.2.3双引号

在双引号包围字符(" "")保留了引号中的所有字符的字面意义,例外$,`,\,和,启用了历史扩展的时候,!.字符$`在双引号内保留其特殊含义(请参阅Shell Expansions)....


Jon*_*ler 5

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

sed -i bak -e 's|OCAMLDIR|'"${PREFIX}"'|g' ocamloptrev
Run Code Online (Sandbox Code Playgroud)

或者你甚至可以使用:

sed -i bak -e "s|OCAMLDIR|${PREFIX}|g" ocamloptrev
Run Code Online (Sandbox Code Playgroud)

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

就个人而言,我会使用.bak而不仅仅是bak作为后缀。