сложная операция поиска / удаления / перемещения / замены с использованием sed? - PullRequest
0 голосов
/ 12 марта 2020

после нескольких часов поисков и экспериментов, я надеюсь, что кто-то может или помочь мне, или потереть мне нос в пропущенном мной сообщении, которое на самом деле было бы полезно, а также подумать об этом ...

Проблема: я сделал быстрое и грязное исправление в нескольких десятках php сценариев (мы используем для улучшения умных возможностей) с проверками безопасности. Пример ввода (part1):

///// SMARTY AUTH /////
    $auth['model']                  = isset($params['model'])               ? $params['model']               : null;
    $auth['requiredLevel']          = isset($params['requiredlevel'])       ? $params['requiredlevel']       : null;
    $auth['baseAuthorizationLevel'] = isset($params['_authorizationlevel']) ? $params['_authorizationlevel'] : null;
    $auth['defaultRequiredLevel']   = AuthorizationLevel::AULE_WRITE;
    $auth['baseModel']              = $smarty->getTemplateVars('model');
///// SMARTY AUTH /////

..., который я хотел бы заменить на более чистое решение, которое мы придумали. Теперь вот загвоздка; в одном разделе файла есть блок строк, к счастью, с очень четкими разделителями, но в одной из этих строк находится фрагмент кода, который необходимо объединить со строкой замены, которая заменяет второй шаблон в строке, следующей за блок, упомянутый ранее, с необязательным переменным числом строк между ними.

У меня проблемы с выяснением того, как соединить этот вложенный код, так как сокращенный код sed меня довольно смущает.

До сих пор я пытался собрать код, необходимый для захвата первого блока, но sed продолжает выдавать мне одну и ту же ошибку каждый раз; дополнительные символы после команды Вот некоторые попытки, которые я предпринял:

sed -n 'p/^\/\/\/\/\/ SMARTY AUTH \/\/\/\/\/\\n.*\\n.*\\n.*\\n.*AULE_\([A-Z_]*\);$^.*$^^\/\/\/\/\/ SMARTY AUTH \/\/\/\/\/$/' function.xls_form.php
sed -n 'p/\(^.*SMARTY AUTH.*$^.*$^.*$^.*$^.*AULE_\([A-Z_]*\);$^.*$^.*SMARTY AUTH.*$/' function.xls_form.php

вторая часть относительно проста по сравнению с первой;

sed -ei'.orig' 's/RoleContextAuthorizations::smartyAuth(\$auth)/$smarty->hasAccess(\$params,AuthorizationLevel::AULE_\1)/' *.php

где \ 1 будет соответствующим фрагментом из первой части ...

Редактировать: первый кодовый блок является примером входной части 1, которую необходимо удалить; часть 2 - RoleContextAuthorizations::smartyAuth($auth), которую необходимо заменить на $smarty->hasAccess($params, AuthorizationLevel::AULE_<snippet from part1>) / edit. Надеясь, что кто-нибудь может указать мне правильное направление, Большое спасибо заранее !!!

1 Ответ

2 голосов
/ 12 марта 2020

Пространство удержания будет ключевым для решения этой проблемы. Вы можете скопировать материал из пространства образца (где обычно работает sed) в пространство удержания и выполнять различные операции с пространством удержания и т. Д. c.

Вам необходимо найти тип AuthorizationLevel::AULE_WRITE текст в маркерах блока, скопируйте его в область удержания и затем удалите текст в маркерах блока. А затем отдельно найдите другой шаблон и замените его информацией из пространства удержания.

Учитывая, что маркеры используют косую черту, также пришло время использовать пользовательский маркер поиска, представленный обратным слэсом sh. В файле script.sed может быть указано следующее:

sed -f script.sed function.xls_form.php

Если вы уверены, что он работает, вы можете поиграть с -i параметрами, чтобы перезаписать оригинал.

\%///// SMARTY AUTH /////%,\%///// SMARTY AUTH /////% {
    /.*\(AuthorizationLevel::AULE_[A-Z]\{1,\}\).*/{
        s//$smarty->hasAccess($params,\1);/
        x
    }
    d
}
/RoleContextAuthorizations::smartyAuth($auth)/x

Первая строка ищет маркер начала и конца, используя \%, чтобы изменить разделитель на %. Затем есть группа действий в фигурных скобках. Вторая строка ищет уровень авторизации и запускает вторую группу действий. Команда замены заменяет строку желаемой строкой вывода. x меняет пространство образца и пространство удержания, копируя желаемую выходную строку в пространство удержания (и копируя пустое пространство удержания в пространство образца - это x для образца обмена и пространства удержания). Это сохранило информацию об уровне авторизации. Внутренний блок заканчивается; внешний блок удаляет строку и продолжает выполнение. Обратите внимание, что в большинстве случаев нет необходимости экранировать символ $ - будет иметь значение, если он находится в конце шаблона (есть разница между /a\$/ и /a$/, но нет разницы между /b$c/ и /b\$c/).

Последняя строка затем ищет строку RoleContextAuthorizations и заменяет ее пробелом. Все остальное просто пропускается.

Учитывая data файл, содержащий:

Gibberish
Rhubarb

///// SMARTY AUTH /////
    $auth['model']                  = isset($params['model'])               ? $params['model']               : null;
    $auth['requiredLevel']          = isset($params['requiredlevel'])       ? $params['requiredlevel']       : null;
    $auth['baseAuthorizationLevel'] = isset($params['_authorizationlevel']) ? $params['_authorizationlevel'] : null;
    $auth['defaultRequiredLevel']   = AuthorizationLevel::AULE_WRITE;
    $auth['baseModel']              = $smarty->getTemplateVars('model');
///// SMARTY AUTH /////

More gibberish
More rhubarb - it is good with strawberries, especially in yoghurt

RoleContextAuthorizations::smartyAuth($auth);

Trailing gibbets — ugh; worse are trailing giblets
Finish - EOF

Вывод sed -f script.sed data:

$ sed -f script.sed data
Gibberish
Rhubarb


More gibberish
More rhubarb - it is good with strawberries, especially in yoghurt

$smarty->hasAccess($params,AuthorizationLevel::AULE_WRITE);

Trailing gibbets — ugh; worse are trailing giblets
Finish - EOF
$

Я думаю, что это то, что было нужно.

Вы можете конвертировать файл скрипта sed в одну строку гиббери sh, но это оставлено в качестве упражнения для читателя - это не очень сложно, но GNU sed и BSD (macOS) sed имеют разные правила, когда вам нужны точки с запятой как часть однострочной команды; Вы были предупреждены. Существуют также различия в правилах для опции -i между вариантами GNU и BSD sed.

Если вам нужно сохранить некоторые части строки RoleContextAuthorizations::smartyAuth, вам придется работать усерднее, но это, вероятно, можно сделать. Например, вы можете добавить пространство удержания в текущее пространство шаблона с помощью команды G, а затем отредактировать информацию в нужных местах. Проще всего, если каждое место, где встречается строка, должно выглядеть одинаково, кроме строки AULE_XYZ - это то, что я здесь предположил.

Кроме того, обратите внимание, что вместо h используется x или g ленив - но не имеет значения, если есть только одна RoleContextAuthorizations::smartyAuth строка. Использование альтернатив означает, что если файл имеет несколько RoleContextAuthorizations::smartyAuth строк, вы сможете выполнить одну и ту же подстановку в каждой, если в файле нет другого ///// SMARTY AUTH /////.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...