1

Я пытаюсь придумать сценарий 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()

Но почему это не заменяет Dashboard на __construct?:

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

Любой другой совет по этому вопросу будет приветствоваться. Мое намерение состоит в том, чтобы обернуть это в сценарий оболочки, который вносит кучу других изменений, мигрируя из древней версии php codeIgnitor в текущую версию.

1 ответ1

0

' У вас есть только до s/… выходит из режима одиночной кавычки, в результате чего весь s/\1/__construct/ (до ' , который будет обработан , как некотируемых вашей оболочкой. В этом режиме \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(/;
    }
'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .