Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 使用Perl如何读入文件并解析日志以查找错误日志并输出到log.txt文件_Regex_Perl - Fatal编程技术网

Regex 使用Perl如何读入文件并解析日志以查找错误日志并输出到log.txt文件

Regex 使用Perl如何读入文件并解析日志以查找错误日志并输出到log.txt文件,regex,perl,Regex,Perl,我试图使用Perl创建一个程序,该程序将读取40000多行长文件的数据,并解析每条消息,从中提取错误消息 我使用的数据示例如下所示: --------All Messages--------- SUCCESS: data transferred successfully . SUCCESS: data transferred successfully . SUCCESS: data transferred successfully . ERROR: there was an error tran

我试图使用Perl创建一个程序,该程序将读取40000多行长文件的数据,并解析每条消息,从中提取错误消息

我使用的数据示例如下所示:

--------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根据结果,它以成功或错误开始

2所有消息将以结尾

下面是我编写的代码,但由于某些原因,我似乎无法调试它。非常感谢您的帮助

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);
    }
}

将换行符添加到分隔符中。更改:

$/ = " .";
致:

如果你想删除分隔符,你可以选择


将换行符添加到分隔符中。更改:

$/ = " .";
致:

如果你想删除分隔符,你可以选择

文件句柄输出在for循环中关闭,您在关闭后每次迭代都会访问该for循环。将其移到循环外并尝试它

文件句柄输出将在for循环内关闭,关闭后您将在每次迭代中访问该for循环。将其移到循环之外,然后尝试设置$/=。您读取的行将以该结束点结束,下一行将以其后面的换行符开始。这意味着除了第一行之外,您的所有行都不会以错误开头-它们将以\n错误开头,因此测试将始终失败

您的代码还有一些其他问题需要了解

您必须始终使用strict和use warnings,并使用my声明所有变量,尽可能接近它们的第一个使用点

您应该始终将词汇文件句柄与open的三参数形式一起使用。您还需要检查每个打开和放置$的状态!这样你就知道它为什么失败了。所以

open(FH,$filetoparse);
变成

open my $in_fh, '<', $filetoparse or die qq{Unable to open "$filetoparse" for input: $!};
下面是对代码的重写,演示了这些要点

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 $!;
    }
}
设置$/=的问题。您读取的行将以该结束点结束,下一行将以其后面的换行符开始。这意味着除了第一行之外,您的所有行都不会以错误开头-它们将以\n错误开头,因此测试将始终失败

您的代码还有一些其他问题需要了解

您必须始终使用strict和use warnings,并使用my声明所有变量,尽可能接近它们的第一个使用点

您应该始终将词汇文件句柄与open的三参数形式一起使用。您还需要检查每个打开和放置$的状态!这样你就知道它为什么失败了。所以

open(FH,$filetoparse);
变成

open my $in_fh, '<', $filetoparse or die qq{Unable to open "$filetoparse" for input: $!};
下面是对代码的重写,演示了这些要点

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 $!;
    }
}

如果它是一个40k行的文件,为什么要在内存中读取它呢?我猜如果您将测试更改为$msgarray[$I]=~/^$errortarget/m,这将允许在记录的前导换行符后匹配^s,那么代码将正常工作。发布代码后请不要修复代码。它将其他人的评论和解决方案置于上下文之外。对不起,博罗丁,使用这个网站还是比较新的。我将更好地继续遵循SOP。如果它是一个40k行的文件,为什么要在内存中全部读取它?我猜如果您将测试更改为$msgarray[$I]=~/^$errortarget/m,这将允许^s与记录中的前导换行符匹配,那么代码将正常工作。请不要在发布后修复代码。它将其他人的评论和解决方案置于上下文之外。对不起,博罗丁,使用这个网站还是比较新的。我会继续跟进SOP的。谢谢你的帮助!你能告诉我为什么我的代码不起作用吗?不管是哪一行有错误还是什么?我知道我的代码很糟糕,这就是我在当地大学学习perl入门课程的方式,我很好奇我的代码在哪里失败了。如果你能帮忙,谢谢你@Drubs1181:正如我说过的几次,问题是您设置了$/=。因此,每条记录的开头都有一个换行符,/^ERROR/不匹配。这非常有帮助!你能告诉我为什么我的代码不起作用吗?不管是哪一行有错误还是什么?我知道我的代码很糟糕,这就是我在当地大学学习perl入门课程的方式,我很好奇我的代码在哪里失败了。如果你能帮忙,谢谢你@Drubs1181:正如我说过的几次,问题是您设置了$/=。因此,每条记录的开头都有一个换行符,/^ERROR/不匹配,这是不正确的。结束在while和for循环之外,这是不正确的。闭合在while和for循环之外
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 $!;
    }
}