Perl根据条件解析文件

时间:2013-08-21 00:07:36

标签: regex perl if-statement data-structures

我有一个非常大的日志文件,会定期更新。它如下:

commands: (List of files to be copied)
Exit time: Fri May 10 05:33:00 2013
Exit status: 2

commands: (List of files to be copied)
Exit Time: Fri May 20 05:34:00 2013
Exit status: 2

commands: (List of files to be copied)
Exit Time: Fri May 30 05:50:00 2013
Exit Status: 1

我有以下代码,它根据退出状态

创建一个哈希
while ($line = <FH>) {
        if ($line =~ /Exit time/) {
        ($exittime, $exittimeval) = split(': ',$line);
         $stat{$qbsid} = {
            time     => $exittimeval
            };
}

我现在需要根据本地时间创建一个时间戳,这样脚本就不会在时间戳(localtime)之后比较日志文件的时间。我有代码来比较时间如下

 $date1 = "$hr1:$min1:$sec1, $moy1/$dt1/$yr1";
 $date2 = "$hr2:$min2:$sec2, $moy2/$dt2/$yr2";
 sub to_comparable {
    my ($date) = @_;
    my ($H,$M,$S,$d,$m,$Y) = $date =~ m{^(\d+):(\d+):(\d+), (\d+)/(\d+)/(\d+)\z}
      or die;
    return "$Y$m$d$H$M$S";
}

if (to_comparable($date2) > to_comparable($date1)) {
print "right\n";
} else {
        print "wrong \n";
}

这里$ hr1,$ min1,$ sec1,$ moy1,$ dt1和$ yr1是本地时间变量,而$ hr2,$ min2,$ sec2,$ moy2,$ dt2和$ yr2是从哈希获得的值。

优选地,在第一次运行时,它应该比较整个文件并创建时间戳。之后,上述想法开始了。

如果有任何问题,请纠正我。谢谢。

2 个答案:

答案 0 :(得分:2)

您可能需要考虑使用Time::Piece,它是首次使用perl v5.9.5发布的。

#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;

{
    my $end_date = '2013-05-30';

    local $/ = '';
    while (<DATA>) {
        if (/^Exit Time: (.+)/m) {
            my $date = Time::Piece->strptime($1, "%c");
            print $date->ymd, "\n" if $date->ymd lt $end_date;
        }
    }   
}

__DATA__
commands: (List of files to be copied)
Exit Time: Fri May 10 05:33:00 2013
Exit status: 2

commands: (List of files to be copied)
Exit Time: Fri May 20 05:34:00 2013
Exit status: 2

commands: (List of files to be copied)
Exit Time: Fri May 30 05:50:00 2013
Exit Status: 1

输出:

2013-05-10
2013-05-20

答案 1 :(得分:0)

您将形成一个20位数字(假设年份为4位数,其余数字始终为2位数)。这是一个很大的数字,但在我的64位UNIX操作系统上似乎很好;我不知道你的。无论如何,使用固定长度的字符串,如果数字很大是一个问题,你可以进行字符串比较(“ge”而不是“&gt;”)。

如果任何输入(例如$ moy1)可能是一位数,那么您的比较功能将无效,因为10月1日(2013101)将在9月30日(2013930)之前。您可以使用以下内容来要求固定的位数:

my ($H,$M,$S,$d,$m,$Y) = $date =~ m{^(\d\d):(\d\d):(\d\d), (\d\d)/(\d\d)/(\d\d\d\d)\z}
      or die;

我确定如何设置$ qbsid(来自退出状态或其他内容),但由于您的代码不完整,我假设您还有其他事情要做。

我也不确定你原来的时间字符串(例如“Fri May 30 05:50:00 2013”​​)如何变成“$ hr1:$ min1:$ sec1,$ moy1 / $ dt1 / $ yr1 “格式,但我假设你也在其他地方这样做。