如何在单个 sed 命令中使用变量和非变量?

如何在单个 sed 命令中使用变量和非变量?

我正在尝试用它sed替换一些 PHP 行。

我的问题是我想用包含 Bash 变量的字符串替换包含 PHP 变量的行。

以下是一个例子:

sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/'$bucketname'.s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

如您所见,我想用$sUrl . $this->_sOutDir包含 Bash 变量的 s3 URL 替换(字面意思)。我尝试使用双引号,但它不起作用:

 sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/"$bucketname".s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

我也尝试使用s/...双引号中的完整形式,但它不起作用,因为sed认为第一个变量也是 Bash 变量。

结果是:

return https://.s3.amazonaws.com . $this->_sOutDir . '/';

答案1

你可以采用两种不同的方式:

  1. 使用单引号:跳出单引号并引用变量(使用双引号来防止单词拆分和文件名扩展):

    sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/'"$bucketname"'.s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php
    
  2. 使用双引号:转义$要按字面意义处理的字符:

    sudo sed -i "s/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php
    

然而,需要注意的是:如果$bucketname包含sed特殊字符/序列,sed命令将会中断(在这种情况下,由于变量要在替换部分中扩展,所以需要担心它可能包含分隔符、意外的反向引用或&

解决这个问题的一种方法是&通过转义可能的分隔符、意外的反向引用和字符来预先清理变量以防止它们被如此解释。

另一种方法是使用 Perl 而不是sed,将变量直接传递给 Perl,它将在替换时处理特殊字符($即使在此方法中使用单引号,也必须对要按字面意思处理的字符进行转义):

sudo perl -i -spe 's/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' -- -bucketname="$bucketname"
$ echo '$sUrl . $this_sOutDir' | perl -spe 's/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' -- -bucketname="string/with/separators/&/and/accidental\$1backreferences"
https://string/with/separators/&/and/accidental$1backreferences.s3.amazonaws.com . $this->_sOutDir

相关内容