2017-11-24 18 views
0

一度に読み込んだ1つのファイルを一度に開き、別のファイルを開き、2番目のファイルの最初のファイルから読み込んだ行の一部を検索し、すべてのインスタンスを他の部分に置き換えようとします私はそれを実行しているときに私はコンソール上で結果を見ることができるが、ファイルが変更されていない最初のfile.Whenから読み取った行の。何が間違いかもしれない。ある人がこれを提案してもらえますか?perlでファイルの内容を変更する方法は?

use strict; 
use warnings; 
use autodie; # die if problem reading or writing a file 

my $filename = 'compare.txt'; 
open(my $fh, '+<', $filename) or die "Could not open file '$filename' $!"; 



while(<$fh>){ 
    my $readline= "$_"; 

    print("\n"); 

    my @arr=split(',',$readline); 
    print($arr[0]."\n".$arr[1]); 
    replace($arr[0],$arr[1]); 

} 
close $fh; 

sub replace 
{ 
    my $search=shift(@_); 
    my $replace=shift(@_); 

    my $filename2 = 'replace.txt'; 
    open(my $fh1, '+<', $filename2) or die "Could not open file '$filename' $!"; 

    while(<$fh1>) 
    { 
     my $readline2= "$_"; 
     $readline2=~s/$search/$replace/g; 
     print($readline2); 
     print("\n"); 

    } 
    close $fh1; 

} 
+2

あなたが書くことはありませんあなたファイルを置き換えるだけで、コンソールに出力するだけです。新しいファイル(変更あり)を書き込んだ後、変更する必要のあるファイルに移動する必要があります。 – zdim

+0

'+ <'モードは必要ありません(使用しないでください)。読んで私の$ fh、<、$ file ... 'を開いてください。 – zdim

+0

'while(my $ readline = <$fh>){..}'を実行でき、 '$ readline'は' $ _'にあった行に割り当てられ、ループ内に存在します(見えます)。 – zdim

答えて

1

あなたのサブファイルでは、ファイルの行を繰り返しているときにファイルに書き戻す必要があります。正規表現の代理者は自動的にそれをファイルに書き戻しません。

use strict; 
use warnings; 
use autodie; # die if problem reading or writing a file 
use File::Copy; 
my $filename = 'compare.txt'; 
open(my $fh, '+<', $filename) or die "Could not open file '$filename' $!"; 



while(<$fh>){ 
     my $readline= "$_"; 

     print("\n"); 

     my @arr=split(',',$readline); 
     print($arr[0]."\n".$arr[1]); 
     replace($arr[0],$arr[1]); 

} 
close $fh; 

sub replace 
{ 
     my $search=shift(@_); 
     my $replace=shift(@_); 

     my $filename2 = 'replace.txt'; 
     open(my $fh1, '+<', $filename2) or die "Could not open file '$filename' $!"; 
#open file to write to 
     open $newfile, '>', 'replace_tmp.txt'; 
     while(<$fh1>) 
     { 
       chomp; 
       my $readline2= "$_"; 
       $readline2=~s/$search/$replace/g; 
       print($newfile, $readline2); 
       print($newfile, "\n"); 
     } 
     close($fh1); 
     close($newfile); 
     move ('replaced.txt', 'replace.txt'); 
} 

これは簡単な方法です。あなたが戻って同じファイルへの書き込みにFile::Tieを使用して、それをリネーム避ける、またはPath::Tinyモジュールの大ファンとしてperldoc

2

を参照することができ、私は上記のように行うだろう:

use 5.014; 
use warnings; 
use Path::Tiny; 

my %rep = map { split /,/ } path('compare.txt')->lines({chomp => 1}); 
path("replace.txt")->edit_lines(sub { 
    while(my($key,$val) = each(%rep)) { 
     s/$key/$val/g; 
    } 
}); 
+1

_Hey、これはどれくらいクールですか?_また、1回の置換えごとにターゲットファイルを完全に書き換えないようにしています。 – PerlDuck

+0

簡潔さのために+1 – Hameed

関連する問題