使用 sed 中的字符串替换对后向引用的匹配

使用 sed 中的字符串替换对后向引用的匹配

我正在尝试编写一个 sed 脚本来将几百个 php 文件中的构造函数从 php4 样式修改为 php5 样式。我取得了一些进展,但在从 sed 中获取反向引用时遇到了问题。这是一个示例文件:

<?php

class Dashboard extends CI_Controller {

    function Dashboard()
    {
        parent::Controller();   
    }
}

目标是从第一行获取类名(第一行和第二行之间有 0 或 1 个空行)

这按预期工作:

sed -En '/^class\ ([a-zA-Z0-9]+)/ {
    n;H;x;n;H;x;'s/Dash/Derp/';P
}' dashtest.php

给出输出:

function Derpboard()

但是为什么这不能用__construct 替换Dashboard呢?:

sed -En '/^class\ ([a-zA-Z0-9]+)/ {
    n;H;x;n;H;x;'s/\1/__construct/';P
}' dashtest.php

欢迎对此提出任何其他建议。我的目的是将其包装在一个 shell 脚本中,该脚本正在进行大量其他更改,从旧版本的 codeIgnitor php 框架迁移到当前版本。

答案1

'刚才的s/…退出单引号模式,导致整个s/\1/__construct/(直到下一个')被解析为未引用由你的 shell 处理。在此模式下,\1被翻译为1,因此sed最终收到s/1/__construct/

请注意,这是行不通的反正,因为 POSIX 正则表达式中的反向引用sed只能引用相同的正则表达式,以及sed对于使用先前的匹配,没有特殊的语法。

你可能还需要更高级的东西 — — 例如:

perl -pe '
    if (/^class (\w+)/) {
        $class = $1;
    }
    elsif (/^\}$/) {
        $class = "";
    }
    elsif ($class and /function \Q$class\E\(/) {
        s//function __construct(/;
    }
'

相关内容