Find

將所有文件中的一些 ASP 程式碼更改為 PHP 程式碼

  • June 9, 2013

我正在將包含相當簡單的 ASP 程式碼的文件目錄遷移到 PHP 伺服器,我需要使用查找和替換機制修改所有文件的內容。我不擅長正則表達式,但我已經用它來改變一些事情:

find . -name "*.php" -print0 | xargs -0 -n 1 sed -i -e 's/oldstring/newstring/g'

不過,我有一些複雜的字元串需要替換。請參閱以下內容:

從:

<% if request("page") = "" then %>

到:

<?php if(!isset($_GET['page']) || !$_GET['page']){ ?>

這一個,* 可以是任何數字,然後將那個數字保留在“TO”上 * 所在的位置。

從:

<% elseif request("page") = "*" then %>

到:

<?php } elseif($_GET['page'] == '*'){ ?>

最後一個非常簡單。從:

<% end if %>

到:

<?php } ?>

如果我可以在目錄中遞歸地批量執行它,這將修復這些文件中 98% 的所有 ASP 程式碼。我試圖以多種方式轉義這些字元串,但無法弄清楚如何讓它執行。任何幫助表示讚賞!

有多種方法可以做到這一點,我建議利用 Perl 的quotemeta功能。

首先,製作一個製表符分隔的文本文件,其中包含第一列中的搜尋模式和第二列中的替換:

$ cat pats.txt                     
<% if request("page") = "" then %>  <?php if(!isset($_GET['page']) || !$_GET['page']){ ?>
<% elseif request("page") = "*" then %> <?php } elseif($_GET['page'] == '*'){ ?>
<% end if %>    <?php } ?>

我創建了一個測試文件,其內容是:

$ cat foo.asp 
<% if request("page") = "" then %>
<% elseif request("page") = "*" then %>
<% end if %>

和 Perl 來拯救:

find . -name "*.php" | while IFS= read -r file; do
 perl -i.bak -e 'open(A,"pats.txt");
            while(<A>){chomp; @a=split(/\t/); $k{quotemeta($a[0])}=$a[1]}
            while(<>){ 
             foreach $pat (keys(%k)){
               s/$pat/$k{$pat}/;
             } 
            print}' $file;
done

Perl 的-i標誌就像在 中一樣sed,你可以指定一個可選的備份後綴。foo.php.bak在上面的範例中,將為每個已處理的文件創建一個名為的文件。-i如果您不想要備份,請單獨使用。

解釋:

該腳本將讀取模式和替換並將模式保存為雜湊 ( %k) 的鍵,其中替換是值。該quotemeta函式轉義所有非 ASCII(不匹配[A-Za-z_0-9])字元。

他們的腳本打開第二個文件,在每一行中查找每個模式並相應地替換。由於搜尋模式已被轉義,quotemeta因此可以正確辨識。

筆記

這顯然不是最有效的方法,因為它必須查找每行上的每個模式。儘管如此,它仍然有效,並且比試圖手動逃避所有事情要簡單得多。

對於名稱中包含新行的文件,該腳本將失敗。我認為這不會是一個問題。

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