2

よく使う

perl -pi -w -e 's/search/replace/g;' [filelist]

[filelist] のすべてのファイルで、「検索」の各出現を「置換」に置き換えます。残念ながら、すべてのファイルのタイムスタンプが更新されているようです。ファイルに「検索」が表示されない場合でも。これを簡単な方法で変更できますか?

4

3 に答える 3

2

簡単ではありません。起こっていることは、perl がファイルを正規表現に通した結果でファイルを上書きしていることだけです。

より長いプログラムで実行できますが、この動作を停止する簡単なフラグはありません。

于 2012-05-01T16:22:40.103 に答える
2

-i大まかに:

rename($ARGV, "$ARGV$^I") or die $! if length $^I;
open(*ARGV, '<', "$ARGV$^I") or die $!;
open(*STDOUT, '>', $ARGV) or die $!;

ご覧のとおり、常に既存のファイルをすぐに置き換えます。それは、すべてのプリント ( -p) が出力を送信する場所です。

2 つのオプション:

  1. 一時ファイルを使用します。

    perl -e'
       $temp_qfn = "temp";
       open(my $fh_out, ">", $temp_qfn) or die $!;
       my $save;
       while (<>) {
          $save = 1 if s/search/replace/g;
          print($fh_out $_);
       } continue {
          if (eof) {  # Not eof()!
             close($fh_out);
             rename($temp_qfn, $ARGV) if $save;
             $save = 0;
             open(my $fh_out, ">", $temp_qfn) or die $!;
          }
       }
    
       close($fh_out);
       unlink($temp_qfn);
    ' file ...
    
  2. ファイル全体をメモリにロードします。

    perl -0777ne'
       if (s/search/replace/g) {
          open(my $fh_out, ">", $ARGV) or die $!;
          print($fh_out $_);
       }
    ' file ...
    

(上記の両方には、さまざまな解決可能なエラー処理の問題-iがあります。同じ問題がいくつかあります。)

于 2012-05-01T19:34:00.097 に答える
1

perldoc perlrunから:

-i[*extension*]

" " コンストラクトによって処理されるファイルをその<>場で編集することを指定します。これは、入力ファイルの名前を変更し、出力ファイルを元の名前で開き、その出力ファイルをprint()ステートメントのデフォルトとして選択することによって行われます。拡張子が指定されている場合は、古いファイルの名前を変更してバックアップ コピーを作成するために使用されます。次の規則に従います。

拡張子が指定されていない場合、バックアップは作成されず、現在のファイルが上書きされます。

鉱山を強調します。

これに対処するには、 の各ファイルの一時ファイルを開き、@ARGV元のファイルから読み取り、置換を行い、その行を一時ファイルに書き込み、置換によってファイルが変更されたかどうかを追跡するプログラムを作成する必要があります。オリジナルライン。ファイルの終わりに達したときに、s///呼び出しによって変更があった場合、一時ファイルの名前が元のファイルに変更されます。eofはFile::Tempモジュールと同様にこれに役立ちます。

于 2012-05-01T16:21:14.607 に答える