2016-05-02 15 views
0

私はPerlの専門家で、特定のプロジェクトの新しいコードを学習しようとしています。つまり、フォルダ内のすべてのXMLファイルを検索して特定の数値を検閲するスクリプト(osx上で)を作成しています。 1ライナーが助けてくれたかもしれないが、ファイルの量はかなり膨大(数千のファイル)になり、定期的に発生するので、それを行うためのスクリプトはより良いものになるだろう。また、スクリプトの部分を学習することがあります:)Perlスクリプトから空白の出力ファイルが返される

私は自分のファイルを開いて、私の特定のニーズに合わせて元のすべての行に正規表現を働かせ、新しい情報の書き込み可能な一時ファイルを生成することができました。これは物事が働くのを止める場所です。ループの後に新しいファイルを古いファイルにコピーしようとしましたが、空白の(!)ファイルで終了します。私は一時ファイルにエラーがあると思っていましたが、それは完璧に見えます。私はnoobsの方法として、オープンモード(読み取り)を変更した後に、元のファイルにテンポラリからラインごとにプロセスを逆行させようと試みましたが、空のファイルも与えました。

今、私の頭は一種の空です。任意のヘルプをいただければ幸いです:)

#!/usr/bin/perl 
use strict; 
use warnings; 
use File::Copy; 

chdir "/perltest/test"; #debugsafety 

#file 
my $workingfiles = "*.XML"; 
my @files = glob("$workingfiles"); 

#process files 
my $old; 
my $tmpfile; 

foreach my $file (@files) { 
    print "$file \n"; 

    open ($old, "<", $file) or die "No file"; 
    open ($tmpfile, ">", 'temp.tmp') or die; 
    while(my $line = <$old>) { 
    my $subz = $line; 
    $subz =~ s/([[:upper:]]{2}[[:digit:]]{6})|([[:upper:]]{1}[[:digit:]]{7})|(?:(?<![[:digit:]])[[:digit:]]{8}(?![[:digit:]])|([[:upper:]]{2}[[:digit:]]{5}[AB]))/**CENS**/g; 
    print $subz; 
    print $tmpfile $subz; 
    } 
    print "Start copying.\n"; 

    open (my $old, ">", $file) or die "No file"; 
    open (my $tmpfile, "<", 'temp.tmp') or die; 

    #copy $tmpfile, $old or die "Couldn't copy"; 
    my $y = 0; #debug 
    while (my $line = <$tmpfile>) { 
     print $y++; #debug 
     my $subz = $line; 
     print $subz; 
     print $old $subz; 
    } 
} 

print "Complete.\n"; 
exit; 
+1

ループの後半で、より高いスコープ変数( '$ old'と' $ tmpfile')を再宣言してください...しないでください。私はまずそれをチェックするだろう。また、読み込み/書き込みの役割を入れ替えるときにファイルハンドラを開いているが閉じていない。 – eballes

+0

なぜあなたの 'copy'行をコメントアウトしましたか? – toolic

+0

私がコピーをコメントアウトしたのは、それが私に空白のファイルを与えたからです。コメントされたコピーの後のコードは同じことをやっている私の2回目の試みでした:) – LaMa

答えて

2

ファイルハンドルを閉じる前に再度開いてください。私はPerl開発者として偽装しているOracle DBAですので、その理由を説明することはできません。しかし、ファイルハンドルを閉じると、スクリプトはそのまま動作するはずです。

close ($old); # add this line 
close ($tmpfile); # add this line 

print "Start copying.\n"; 

あなたがそれらに戻って「コピー」で行われたときにそれらを再び閉じることをお勧めだろう。

0

ファイルハンドルの書き込みが完了したら、ファイルハンドルを明示的に閉じます。あなたがそれをするまで、物事はまだバッファリングされます。 もむしろファイルをループ(またはファイル::コピー::コピーを使用して)それのバックアップコピーを作成するよりも、

rename($file, "$file.old"); 
rename("temp.tmp", $file); 

に、より理にかなって。

最後に、簡単な編集のために、コマンドラインでそれをやってもらうのに慣れさせて、頭を傷つける必要はなく、 "前回のスクリプトで何をしたのですか?長期的には大きな時間節約になる可能性があります。

perl -p -i.bak -e 's/pattern/text/;' files* 

は一般的な形式です。

関連する問題