[英]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
而不是h
或g
是惰性的——但如果只有一個RoleContextAuthorizations::smartyAuth
行也RoleContextAuthorizations::smartyAuth
。 使用替代方法意味着如果文件有多個RoleContextAuthorizations::smartyAuth
行,那么您可以在每個行中進行相同的替換,除非文件中還有另一個///// SMARTY AUTH /////
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.