[英]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 warnings
並use 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 $!;
}
}
文件句柄OUTPUT
在for
循環中關閉,您在關閉后每次迭代都可以訪問該循環。 將其移出循環並嘗試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.