使用perl one liner進行檔案搜尋取代的流程(SOP)
By Sigmund Tzeng
- 1 行有餘力 則以學文: 使用perl one liner進行檔案搜尋取代的流程(SOP)
- 2 行有餘力 則以學文: 使用 perl one liner 進行檔案搜尋取代的流程(SOP)(二)
- 3 行有餘力 則以學文: 使用 perl one liner 進行檔案搜尋取代的流程 ( SOP ) ( 三 )
1 行有餘力 則以學文: 使用perl one liner進行檔案搜尋取代的流程(SOP)
- 第一步是找出要取代的標的,利用 perl -ne ‘print if m/pattern/’ filename 確認
- 要做什麼樣的改寫?利用 perl -ne ‘print if s/pattern/pattern2/’ filename 確認
- 試試看結果.利用 perl -pe ’s/pattern/pattern2/’ filename 確認
- 加入i參數以進行更動. perl -pi -e ’s/pattern/pattern2/’ filename
ps.取代部要使用函數呼叫的話,參考 http://www.perlmonks.org/?node_id=638259 ,簡言之就是使用/e選項或 @{[…]}結構
例如,將srt字幕檔延遲5秒
perl -p -i.bak -e “s/(():():())/@{[sprintf(’%02d’,int(($4+60*$3+3600*$2+5) \/ 3600))]}:@{[sprintf(’%02d’,int((($4+60*$3+3600*$2+5) % 3600 \/ 60) ))]}:@{[sprintf \"%02d\”,($4+60*$3+3600*$2+5) % 60]}/g;" srt.srt
2 行有餘力 則以學文: 使用 perl one liner 進行檔案搜尋取代的流程(SOP)(二)
承接 行有餘力 則以學文: 使用perl one liner進行檔案搜尋取代的流程(SOP) 一文的第 2 步驟,由於使用 one-liner 時如果要進行取代,沒有什麼空間去做額外的判斷,因此在取代字串很可能必需向前參考所找到的 subgroup 。全寫在一行易讀性的確滿不好,但是這是 perl 的簡潔所必需付出的代價。
原理參考: http://www.perlmonks.org/?node_id=687031 http://perldoc.perl.org/perlretut.html#Non-capturing-groupings
例如想把文字:
2.1 67
取代成
2.2 67
在 windows 平台上的寫法是像這樣的:
perl -ne “print if s/^(\*+ +[ ]+)?$/eval q{\"$1:drill:\”}/e and defined $1" abc.txt
或是更簡潔一點:
perl -ne “print if s/^(\*+ +[ ]+)?$/q{\"$1:drill:\”}/ee and defined $1" abc.txt
一樣的道理可推到第 3、4 步,但不用去 test 有沒有發生取代:
perl -pe “s/^(\*+ +[ ]+)?$/q{\"$1:drill:\”}/ee" abc.txt
perl -pi -e “s/^(\*+ +[ ]+)?$/q{\"$1:drill:\”}/ee" abc.txt
3 行有餘力 則以學文: 使用 perl one liner 進行檔案搜尋取代的流程 ( SOP ) ( 三 )
承接 行有餘力 則以學文: 使用perl one liner進行檔案搜尋取代的流程(SOP) 一文,如果要串接多個層次的處理也是沒有問題的。(沒辦法,RE 真的是太好用太強大啦!!)
“|” 這個重新導向算子可以把前面的結果傳給後面,所以可以這樣使用:
perl -pe xxxxxxxx abc.txt | perl -ne xxxxxxxxxxxxx > def.txt
另外還可以衍生出一種使用的情境,就是資料的過濾,這必需要 -ne 參數搭配上 print 函數,合於條件時才利用 print 輸出以進入下一層處理。
以下這行簡單的 one-liner 可以證明, | 兩側的 perl instance 是同時執行,且輸出入是即時重導的:
perl -e “$|=1;for($i=1;$i<5;$i++){print \"$i\";sleep($i);}"|perl -pe “print time().\”\”.($_+1).\"\""