2012-08-22 83 views
0

我想組裝一個腳本,它將首先識別在一個文件夾下創建的最新日誌文件,然後打開它並查找特定數據。基本上,我會在這個日誌文件中尋找特定的錯誤並將錯誤打印到新的日誌文件中。Perl腳本來讀取最新的日誌文件

我知道如何才能擁有最新的文件進行排序,但在閱讀最新的文件,並將其複製到新的日誌文件有問題

use File::stat; 

$dirname = 'C:/Luntbuild_Logs'; 
$timediff = 0; 

opendir DIR, "$dirname"; 

while (defined($file = readdir(DIR))) { 
    if ($file ne "." && $file ne "..") { 
     $diff = time() - stat("$dirname/$file")->mtime; 
     if ($timediff == 0) { 
      $timediff = $diff; 
      $newest = $file; 
     } 
     if ($diff < $timediff) { 
      $timediff = $diff; 
      $newest = $file; 
     } 
    } 
} 

print $newest; 

$file1 = "$dirname/$file"; 

open(FILE1, "<$newest"); 
my (@fprint) = <FILE1>; 
close FILE1; 

open(FOUT, ">list1.txt") || die("Cannot Open File"); 

foreach $line (@fprint) { 
    print "$line" if $line =~ /> @/; 
    print "$line" if $line =~ /ORA-/; 
    print FOUT $line; 
} 

close FOUT; 
+0

出了什麼問題?你爲什麼不在這兩個開放中使用「死亡」? – choroba

+0

可能的重複[Perl - 對目錄中的日誌文件進行排序,選取最新生成的日誌文件並僅打印特定數據](http://stackoverflow.com/questions/12050020/perl-sort-the-log-files -from-a-directory-pick-up-latest-generated-log-fil) – Toto

回答

2

主要問題是您在$file1中構建完整文件路徑,但隨後打開僅包含文件名的$newest

你真的應該使用use strictuse warnings在程序的開始,並宣佈與my所有變量在其定義

  • 使用詞彙的逐

    • 始終提高你的代碼文件和目錄句柄以及open參數的三種形式。始終測試開放的狀態,並把$!die串,讓你知道爲什麼它沒有圍繞一個變量

    • 不要把雙引號,除非你知道那是什麼,那就是你想要

    • 什麼

    這裏是你的代碼的重構,其遵循這些準則,並且也使用了內置-M運營商返回的文件中日齡

    use strict; 
    use warnings; 
    
    my $dirname = 'C:/Luntbuild_Logs'; 
    my ($newest_age, $newest_file); 
    
    opendir my $dh, $dirname or die $!; 
    
    while (readdir($dh)) { 
        my $file = "$dirname/$_"; 
        next unless -f $file; 
        my $age = -M $file; 
        unless (defined $newest_age and $newest_age <= $age) { 
        $newest_age = $age; 
        $newest_file = $file; 
        } 
    } 
    
    print $newest_file, "\n"; 
    
    open my $out,'>', 'list1.txt' or die "Cannot open file: $!"; 
    
    open my $in, '<', $newest_file or die $!; 
    while (<$in>) { 
        print if /> \@/ or /ORA-/; 
        print { $out } $_; 
    } 
    
    close $out or die $!; 
    close $in or die $!; 
    
  • +0

    '$ file1'實際上可能是個好主意不包含正確的文件名:它包含readdir的最後一個文件名。 – TLP

    2

    它看起來像你的錯誤可能在於這裏:

    open(FILE1,"<$newest"); 
    

    您嘗試打開不包含路徑的文件(readdir只返回文件名),這可能會或可能無法正常工作,這取決於當前工作目錄是什麼。

    由於您沒有檢查open語句的返回值,所以您不知道它是否失敗。最有可能的,你需要做的是這樣的:

    open FILE1, "<", "$dirname/$newest" or die $!; 
    

    務必檢查所有open的返回值,opendir電話,因爲他們可以靜靜地失敗。並且一定要包括:

    use strict; 
    use warnings; 
    

    在您的腳本中,並更正錯誤和警告。這是您最安全的預防措施,不易發現錯誤。

    +0

    另一個問題是你使用「0」作爲「'$ timediff'尚未設置的特殊值」。假設你的'readdir'返回三個文件名:一個小時前修改了一個文件,一個文件修改了這個時刻,一個文件修改了10分鐘前。在這種情況下,它會在看到第二個文件時再次將'$ timediff'設置爲0,因此認爲第三個文件實際上是最新的 - 即使它不是。或者想象未來的文件時間戳(是的,這種情況通常會發生)。 –

    +1

    正確,將'$ timediff'保留爲未定義將更明智,並檢查定義。但是,我認爲,這不是這個代碼的主要問題。除非有很多文件,否則執行'($ newest,@others)= sort {-M $ a <=> -M $ b} readdir(DIR)' – TLP

    相關問題