在 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
作为后缀。
我正在使用 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
作为后缀。