如果要把所有的文件檔作取代,例如將字串"charset=big5" 改為 "charset=utf-8",文件檔如果不多直接編輯就好,但如果文件檔一多,甚至還放在子目錄裡,就很費工。
還好可以利用PERL的簡單的指令完成:
原字串:
charset=big5
取代後字串:
charset=utf-8
取代目前目錄包括子目錄的所有PHP檔
指令
$ find ./ -type f -name '*.php' -exec perl -i -pe s/charset=big5/charset=utf-8/gi {} \;
說明[2][3]
./ 開始目錄含子目錄尋找
-type f 指定檔案,不含目錄及連結
-name '*.php' 所有 *.php檔
-exec 找到目標後執行後面的指令
-i 直接修改原檔案不建立備份
-p 重複執行直到檔案結束
-e 執行後面的命令
s/charset=big5/charset=utf-8/gi
s 取代
/原字串/換成字串/
g 持續取代到行尾
i 不分大小寫
\; find 指令結束
注意
1. 此項操作不能復原,所以千萬不能打錯字。
2. 此項操作不會有任何回應,除非指令打錯。
3. 這種方法可以擴大使用到所有的取代,換句話說,只要是取代檔案中的文字,就不用一個一個文件開啟
以上的方法對於簡單的比對字串是ok,但是對於複雜的字串取代,這個指令基本上就會出錯,例如要把網址 http://n.sfs.tw/10677 取代為空,這樣寫就出錯
$ find ./ -type f -name '*.php' -exec perl -i -pe s/http:\/\/n\.sfs\.tw\///gi {} \;
主要因為 console 的 shell 是不認識脫逸字元'\'
對於複雜的取代,最好的方法就是寫一個PERL的程式
所以我撰寫一個簡單的取代程式:replace.pl
#!/usr/bin/perl -w if( !$ARGV[0] ) {die "請指定檔案\r\n";} $fn= $ARGV[0]; open(FILE, $fn) or die "$!"; $cnt=0; $data=""; while(<FILE>){ $cnt += ($_ =~ s!http://n\.sfs\.tw/!!ig); $data .= $_; } print "[$fn]總共置換:". $cnt."筆\n"; close( FILE); open( FILE, "> $fn") or die "$!"; print FILE $data; close( FILE);
第3行,這個程式要接受一個傳入的參數,也就是要作取代字串的檔案。
再結合find 指令就能完全的取代:
$ find ./ -type f -name '*.php' -exec ./replace.pl {} \;
強到爆
後記
某外國網友sally看到這篇向我推薦他同事做的 cheatsheet (小抄),有興趣的可以參考一下[4]:
https://www.pcwdld.com/perl-cheat-sheet
參考資料
[1] EcStart PHP 技術討論論壇 http://bbs.ecstart.com/thread-8502-1-1.html
[2] http://stackoverflow.com/questions/6302025/perl-flags-pe-pi-p-w-d-i-t