【问题标题】:Path substitution with sed and shell variables on OS X在 OS X 上使用 sed 和 shell 变量进行路径替换
【发布时间】:2016-01-23 22:01:47
【问题描述】:

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

基本上我有这个:

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

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

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

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

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

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

【问题讨论】:

    标签: shell sed string-interpolation


    【解决方案1】:

    试试这个:

    #!/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)。 ...

    【讨论】:

    • 如果${PREFIX} 包含空格等,第一个代码会遇到问题。您应该将其括在双引号中:'s|OCAMLDIR|'"${PREFIX}"'|g' 以确保安全。否则,你的答案很好。
    【解决方案2】:

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

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

    或者你甚至可以使用:

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-10-06
      • 2014-01-09
      • 2021-09-28
      • 1970-01-01
      • 2015-04-19
      • 2011-01-24
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多