正規表現を使用して、ファイルの任意の行を指定した文字列に置き換えるサブルーチン

use strict;
use warnings;
use File::Basename;
use File::Path;
use File::Temp qw/ tempfile /;
use Fcntl;

my $in  = "a.txt";
my $out = "b.txt";

print "-- infile --\n";
open my $fh, ">a.txt";
while (my $line = <DATA>) {
  print $fh $line;
  print "$line";
}
close $fh;

print "-- okikae --\n";
my $rc =okikae($in, 
       $out,
       {
         # ここのキーに正規表現を入れることが可能
         "413" => "すーぱーうしさんぱわー",
         "414" => "すーぱーうしさんぱわー2",
       }
      );
print "rc=$rc\n";

print "-- diff --\n";
system("diff -Naur $in $out");

sub okikae
{
  my ($infile, $outfile, $hash) = @_;
  my @pattern = keys %$hash;

  if (sysopen my $fh, $infile, O_RDONLY) {
    my ($fh_tmp, $tmpfile) = tempfile(UNLINK => 1);
    
    while (my $line = <$fh>) {
      chomp $line;
      foreach my $ptn (@pattern) {
        if ($line =~ /$ptn/) {
          $line = $hash->{$ptn};
          last;
        }
      }
      print $fh_tmp $line . "\n";
    }
    close $fh;
    close $fh_tmp;
  
    unless (rename $tmpfile, $outfile) {
      print "rename err $tmpfile, $outfile $!\n";
      goto ERROR;
    }
  }
  else {
    print "sysopen err infile $!\n";
    goto ERROR;
  }
  return 1;
ERROR:
  return 0;
}
__END__
413  aptitude moo
414  aptitude -v moo
415  aptitude -vv moo
416  aptitude -vvv moo
417  aptitude -vvvv moo
418  aptitude -vvvvv moo
419  aptitude -vvvvvv moo
420  aptitude -vvvvvvv moo
421  aptitude -vvvvvvvvvv moo
422  aptitude -vvvvvvvvvvvv moo
  • 実行結果
$ perl okikae.pl
-- infile --
413  aptitude moo
414  aptitude -v moo
415  aptitude -vv moo
416  aptitude -vvv moo
417  aptitude -vvvv moo
418  aptitude -vvvvv moo
419  aptitude -vvvvvv moo
420  aptitude -vvvvvvv moo
421  aptitude -vvvvvvvvvv moo
422  aptitude -vvvvvvvvvvvv moo

-- okikae --
rc=1
-- diff --
--- a.txt       2010-07-16 00:31:47.639267098 +0900
+++ b.txt       2010-07-16 00:31:47.639267098 +0900
@@ -1,5 +1,5 @@
-413  aptitude moo
-414  aptitude -v moo
+すーぱーうしさんぱわー
+すーぱーうしさんぱわー2
 415  aptitude -vv moo
 416  aptitude -vvv moo
 417  aptitude -vvvv moo