Perl如何从日志文件中查找特定的开始和结束行?

时间:2014-02-03 12:53:28

标签: perl

文件的结构如下:

<28 Jan 2014 00:08:24>00001 startmessage1
<28 Jan 2014 00:08:24>00001 msg1
<28 Jan 2014 00:08:24>00001 msg1
<28 Jan 2014 00:08:24>00001 startmessage2
<28 Jan 2014 00:08:25>00001 msg2
<28 Jan 2014 00:08:25>00001 msg2
<28 Jan 2014 00:08:25>00001 msg2
<28 Jan 2014 00:08:25>00001 msg2
<28 Jan 2014 00:08:25>00001 msg2
<28 Jan 2014 00:08:26>00001 msg2
<28 Jan 2014 00:08:26>00001 Endmessage2
<28 Jan 2014 00:08:26>00001 msg1
<28 Jan 2014 00:08:26>00001 msg1
<28 Jan 2014 00:08:27>00001 startmessage3
<28 Jan 2014 00:08:27>00001 msg3
<28 Jan 2014 00:08:28>00001 msg1
<28 Jan 2014 00:08:28>00001 msg1
<28 Jan 2014 00:08:30>00001 Endmessage1
<28 Jan 2014 00:08:31>00001 msg3
<28 Jan 2014 00:08:31>00001 msg3
<28 Jan 2014 00:08:31>00001 msg3
<28 Jan 2014 00:08:31>00001 Endmessage3

日期和时间,ID,日志消息......必须找到开始消息和相应的结束消息以计算时间。

输出应该是

28 Jan 2014 00:08:24 |startmessage1 |Endmessage1 |00001| 6 seconds
28 Jan 2014 00:08:24 |startmessage2 |Endmessage2 |00001| 2 seconds

我的代码:

my @startmsg= ("startmessage1","startmessage2","startmessage3");
my @endmsg= ("Endmessage1","Endmessage2","Endmessage3");
print 'THREAD ID,LOG DETAILS'."\n";

     foreach my $filename (glob("$dir/*.out"))
        {
          open(my $fh, "<", $filename) or die "Could not open '$filename'\n";

                while ($line = <$fh>)
                {
                        my $i=2;
                        chomp($line);

                         if($line=~ $startmsg[$i])
                        {
                                chomp ($line);
                                my $threadid=$line;
                                $threadid =~ s!(\d*)\s*.*!$1!;
                                my $startdetails=$line;
                                $startdetails =~ s!(\d*)\s*(.*)!$2!;
                                chomp($threadid);
                                print "$threadid,$startdetails \n";
                                my $flag = 'False';

                               OUTER:  while ($line = <$fh>)
                                {
                                        if ($line=~ m/$threadid/)
                                         if($line=~  $endmsg[$i])
                                                {
                                                chomp ($line);
                                                my $enddetails=$line;
                                                $enddetails =~ s!(\d*)\s*(.*)!$2!;
                                                print "$threadid,$enddetails\n";
                                                $flag='True';
                                                last OUTER;
                                                }

                                        }
                                }
                        }

                }
                 close($fh);
        }

“我能在这个程序中只得到一条开始和结束信息。我也尝试将所有的凝视分配到一个变量中(一个变量中的所有开始消息和一个变量中的所有结束消息)..问题出在后面开始发送消息1,结束消息2被捕获并计算出错误的时差。请帮我解决问题“

注意:开始消息和结束消息不同。我刚才给出了例子。同样,我正在抓几件事

请帮帮我

1 个答案:

答案 0 :(得分:1)

使用DateTime处理日期时间处理。将消息保存为哈希:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use DateTime;

my %message;

sub month2num {
    my $name = shift;
    my %months;
    @months{ qw(Jan Feb Mar Apr May Jun Jul Aug Sep Nov Oct Nov Dec) } = (1 .. 12);
    return $months{$name}
}


while (<>) {
    if (my ($timestamp, $num, $type, $msg)
            = /^ <(.*)> ([0-9]+)\ (start|End) message ([0-9]+) $/x) {
        my ($day, $month, $year, $hour, $minute, $second) = split /[ :]/, $timestamp;
        my $dt = 'DateTime'->new(
                 year   => $year,
                 month  => month2num($month),
                 day    => $day,
                 hour   => $hour,
                 minute => $minute,
                 second => $second,
             );

        if ('start' eq $type) {
            die "Invalid start of $msg\n" if exists $message{$msg};
            $message{$msg} = { start => $dt, num => $num };

        } else {
            die "Invalid end of $msg\n" unless exists $message{$msg};
            my $duration = $dt->epoch - $message{$msg}{start}->epoch;
            say join ' | ', $message{$msg}{start},
                            "startmessage$msg",
                            "Endmessage$msg",
                            $message{$msg}{num},
                            "$duration seconds";
            delete $message{$msg};
        }
    }
}