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

Path substitution with sed and shell variables on OS X

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

基本上我有这个:

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

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

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

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

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

如何将 ${PREFIX} 的正确计算输入到 sed 命令中?

试试这个:

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

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

你基本上做的是“退出”/离开 single-quoted 字符串,进入 double-quoted 字符串,解释 double-quotes 内的变量,然后进入再次使用单引号。

对于这个简单的例子,我们也可以只使用 double-quotes,它允许解释变量:

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

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

如果您尝试在 single-quotes 中使用 double-quotes (""),它们也不会被解释。 This part of the Bash manual 对此进行了更详细的解释。

3.1.2.2 Single Quotes

Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

3.1.2.3 Double Quotes

Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !. The characters $ and ` retain their special meaning within double quotes (see Shell Expansions). ...

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

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

或者您甚至可以使用:

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

后者是安全的,因为双引号内的 material 不包含 shell 元字符(美元符号、反斜杠和 back-quotes 是主要的危险符号)。如果字符串的其余部分有不可靠的字符,第一个版本使用起来更安全。

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