簡體   English   中英

使用Perl如何讀取文件並解析日志以查找錯誤日志並輸出到log.txt文件

[英]Using Perl how to read in a file and parse through logs to find error logs and output to a log.txt file

我正在嘗試使用Perl創建一個程序,該程序將讀取40,000行以上文件的數據,並解析每條消息以從中提取錯誤消息。

我正在使用的數據樣本如下所示:

--------All Messages---------
SUCCESS: data transferred successfully .
SUCCESS: data transferred successfully .
SUCCESS: data transferred successfully .
ERROR: there was an error transferring data .
SUCCESS: data transferred successfully .
SUCCESS: data transferred successfully .
SUCCESS: data transferred successfully .
ERROR: there was an error transferring the data and the error message spans
more than 1 line of code and may also contain newline characters as well .
SUCCESS: data transferred successfully .
SUCCESS: data transferred successfully .
SUCCESS: data transferred successfully .
---------END REPOSITORY---------

日志中的每個消息都有以下共同點:

1)根據結果,它以SUCCESS或ERROR開頭

2)所有消息都將以<whitespace><period><newline>

以下是我編寫的代碼,但由於某種原因,我似乎無法對其進行調試。 任何幫助是極大的贊賞。

open(FH,$filetoparse);
{
# following line is supposed to change the delimiter for the file
    $/ = " .";
# the follow statement will create an error log of all error messages in log and save it
# to a file named errorlog.txt
    while(<FH>)
    {
        push (@msgarray, $_);
    }
if ($outputtype == 1)
{
    $outputfile="errorlog.txt";
    open(OUTPUT,">>$outputfile");
    $errorcount=0;
    $errortarget="ERROR";
    print OUTPUT "-----------Error Log-----------\n";

    for ($i=0;$i<@msgarray;$i++)
    {
    if ($msgarray[$i] =~ /^$errortarget/)
    {

        print OUTPUT "$msgarray[$i]\n";
#       print OUTPUT "next code is: \n";
        $errorcount++;

    }
    print OUTPUT "\nError Count : $errorcount\n";

    close (OUTPUT);
    }
}

將換行符添加到定界符。 更改:

$/ = " .";

至:

$/ = " .\n";

如果要刪除定界符,可以chomp

while(<FH>)
{
    chomp;
    push (@msgarray, $_);
}

設置$/ = " ." 是您閱讀的行將以該結束點結束,而下一行將以其后的換行符開頭。 這意味着除了第一行可能以"ERROR"開頭的所有行外,其他行"\\nERROR"開頭,因此您的測試將始終失敗

您的代碼中還有其他一些您想了解的問題。

  • 必須始終 use strict use warningsuse warnings ,並使用my聲明所有變量,使其盡可能接近它們的第一個使用點。

  • 您應該始終將詞法文件句柄與open的三參數形式一起使用。 您還需要檢查每個open的狀態並放入$! die串中,以便您了解失敗的原因 所以

     open(FH,$filetoparse); 

     open my $in_fh, '<', $filetoparse or die qq{Unable to open "$filetoparse" for input: $!}; 
  • 最好逐行處理文本文件,除非您有充分的理由將它們完整地讀入內存中,例如,如果需要對數據進行多次遍歷,或者需要隨機訪問內容而不是進行處理他們線性。

    還值得注意的是,與其寫作

     while ( <$in_fh> ) { push @msgarray, $_; } 

    你可以說

     @msgarray = <$in_fh>; 

    結果完全一樣

  • 通常最好遍歷數組的內容而不是遍歷數組的索引。 所以代替

     for ( my $i = 0; $i < @msgarray; ++$i ) { # Do stuff with $msgarray[$i]; } 

    你可以寫

     for my $message ( @msgarray ) { # Do stuff with $message; } 

這是對代碼的重寫,展示了這些要點

open my $in_fh, '<', $filetoparse
        or die qq{Unable to open "$filetoparse" for input: $!};

{
    if ( $outputtype == 1 ) {

        my $outputfile  = 'errorlog.txt';
        my $errorcount  = 0;
        my $errortarget = 'ERROR';

        open my $out_fh, '>>', $outputfile
                or die qq{Unable to open "$outputfile" for output: $!};

        print $out_fh "-----------Error Log-----------\n";

        while ( <$in_fh> ) {
          next unless /^\Q$errortarget/;

          s/\s*\.\s*\z//;       # Remove trailing detail
          print $out_fh "$_\n";
          ++$errorcount;
        }

        print $out_fh "\nError Count : $errorcount\n";

        close ($out_fh) or die $!;
    }
}

文件句柄OUTPUTfor循環中關閉,您在關閉后每次迭代都可以訪問該循環。 將其移出循環並嘗試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM