5

Kubuntu (GNU/Linux) で bash シェル (GNU Bash-4.2) 経由で perl (v5.14.2) を使用して、改行文字を含む文字列を検索および置換しようとしていますが、まだ成功していません。

ここに私が探しているテキストファイルがあります:

<!-- filename: prac1.html -->

hello
kitty

blah blah blah

テキスト エディター (Kate の) 検索と置換機能を使用する場合、または正規表現テスター ( http://regexpal.com/ ) を使用する場合、この正規表現を簡単に機能させることができます。

hello\nkitty

しかし、コマンド ラインで perl を使用している場合、次のコマンドはどれも機能しませんでした。

perl -p -i -e 's,hello\nkitty,newtext,' prac1.html
perl -p -i -e 's,hello.kitty,newtext,s' prac1.html
perl -p -i -e 's,hello.*kitty,newtext,s' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,' prac1.html

実際、私は必死になり、これらすべてを含む他の多くのパターンを試しました(「単一行」モードと「複数行」モードでの異なる順列):

perl -p -i -e 's,hello\nkitty,newtext,' prac1.html
perl -p -i -e 's,hello.kitty,newtext,' prac1.html
perl -p -i -e 's,hello\nkitty,newtext,s' prac1.html
perl -p -i -e 's,hello.kitty,newtext,s' prac1.html
perl -p -i -e 's,hello\nkitty,newtext,m' prac1.html
perl -p -i -e 's,hello.kitty,newtext,m' prac1.html
perl -p -i -e 's,hello\nkitty,newtext,ms' prac1.html
perl -p -i -e 's,hello.kitty,newtext,ms' prac1.html

perl -p -i -e 's,hello[\S\s]kitty,newtext,' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,s' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,s' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,s' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,s' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,m' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,m' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,m' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,m' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,ms' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,ms' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,ms' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,ms' prac1.html

(\r \r\n \R \f \D など、グローバルモードも試しました。)

誰でも問題を見つけたり、解決策を提案したりできますか?

4

2 に答える 2

14

これを試してみてください。入力レコード区切り文字(デフォルトでは改行)を変更することでこれを可能にします。

perl -i -p00e 's,hello\nkitty,newtext,' prac1.html

からperldoc perlrun

-0[8進数/16進数]

入力レコード区切り文字($ /)を8進数または16進数として指定します。数字がない場合は、ヌル文字が区切り文字になります。他のスイッチは、数字の前後にある場合があります。たとえば、ヌル文字で終了するファイル名を出力できるバージョンのfindがある場合、次のように言うことができます。

find . -name '*.orig' -print0 | perl -n0e unlink

特別な値00を指定すると、Perlは段落モードでファイルを丸呑みします。値が0400以上の場合、Perlはファイル全体を丸呑みしますが、慣例により、値0777がこの目的で通常使用される値です。

于 2013-02-16T02:21:51.980 に答える
6

問題は、「-p」がすでにこのループを「-e」の周りに暗黙的にラップしており、「<>」が入力を行に分割しているため、正規表現が複数の行を表示する機会が得られないことです。

 LINE:
       while (<>) {
           ...             # your program goes here
       } continue {
           print or die "-p destination: $!\n";
       }

詳細については、perlrun マンページを参照してください。

于 2013-02-16T01:14:40.090 に答える