簡體   English   中英

使用 sed 進行復雜的搜索/刪除/移動/替換操作?

[英]complex search/delete/move/replace operation using sed?

經過幾個小時的搜索和試驗,我希望有人可以幫助我或在我錯過的帖子中擦鼻子,這實際上也會有所幫助,並且想到它......

問題:我在幾十個 php 腳本(我們用來增強 smarty 功能)中進行了快速和骯臟的修復,並進行了安全檢查。 輸入示例(第 1 部分):

///// 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 希望有人能指出我正確的方向,非常感謝提前!!!

保持空間將是解決這個問題的關鍵。 您可以將素材從模式空間( sed通常工作的地方)復制到保留空間中,並使用保留空間進行各種操作等。

您需要在塊標記內找到AuthorizationLevel::AULE_WRITE類型的文本,並將其復制到保留空間,然后刪除塊標記內的文本。 然后分別找到另一個模式並用來自保持空間的信息替換它。

鑒於標記使用斜杠,現在也是使用由反斜杠引入的自定義搜索標記的時候了。 以下內容可以在文件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為交換模式和保持空格)。 這已經保存了 AuthorizationLevel 信息。 內塊結束; 外部塊刪除該行並繼續執行。 請注意,大多數情況下不需要對$符號進行轉義 - 如果它位於模式的末尾會很重要( /a\\$//a$/之間有區別,但/b$c/之間沒有區別/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腳本的文件轉換為單行亂碼,但這留給讀者作為練習——這並不難,但是當您需要分號時,GNU sed和 BSD (macOS) sed有不同的規則單行命令的一部分; 你被警告了。 sed的 GNU 和 BSD 變體之間-i選項的規則也存在差異。

如果必須保留RoleContextAuthorizations::smartyAuth行的某些部分,則必須更努力地工作,但也許可以做到。 例如,您可以使用G命令將保留空間添加到當前模式空間,然后將信息編輯到正確的位置。 如果除了AULE_XYZ字符串之外,該行出現的每個位置都需要看起來相同,這是最簡單的 - 這就是我在這里假設的。

另外,請注意,使用x而不是hg是惰性的——但如果只有一個RoleContextAuthorizations::smartyAuth行也RoleContextAuthorizations::smartyAuth 使用替代方法意味着如果文件有多個RoleContextAuthorizations::smartyAuth行,那么您可以在每個行中進行相同的替換,除非文件中還有另一個///// SMARTY AUTH /////

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM