2016-05-02 60 views
0

我是Perl的總noob,試圖學習一些特定項目的新代碼。簡而言之,我正在製作一個腳本(在osx上),用於搜索文件夾中的所有xml文件並審查特定的數字。我知道一行可能會有所幫助,但文件的數量將非常巨大(數千個文件),並且會定期發生,因此腳本可能會更好。此外,還有腳本部分的學習:)Perl腳本給出了一個空白輸出文件

我設法打開我的文件,使正則表達式工作在原始的每一行上,以滿足我的特定需求,併爲我的新信息生成可寫入的臨時文件。這是停止工作的地方。我嘗試在循環後將新文件複製到舊文件中,但最終得到一個空白(!)文件。我懷疑臨時文件存在錯誤,但看起來很完美。我甚至試圖作爲noobs的出路,在改變打開模式(讀取)之後,將流程從temp恢復到原始文件,但是這也給出了一個空文件。

現在我的頭是空的。任何幫助將不勝感激:)

#!/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

我之所以評論該副本的原因是因爲它給了我一個空白的文件。代碼複製後的代碼是我做同樣的事情的第二次嘗試:) – 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* 

是一般形式。