日期范围问题

时间:2010-06-01 05:40:45

标签: perl

我有一个日志文件,其中每行的前几个字符都作为时间戳。

  

2010-06-01 04:56:02,802 DEBUG   {Thread-27}一些短信

     

2010-06-01 04:56:02,802 DEBUG   {Thread-27}一些短信

     

2010-06-01 04:56:02,802 DEBUG   {Thread-27}一些短信

     

2010-06-01 04:56:02,802 DEBUG   {Thread-27}一些短信

     

2010-06-01 05:22:02,802调试   {Thread-27}一些短信

     

2010-06-01 05:22:02,802调试   {Thread-27}一些短信

     

2010-06-01 05:22:02,802调试   {Thread-27}一些短信

     

2010-06-01 05:22:02,802调试   {Thread-27}一些短信

     

2010-06-01 06:43:02,802 INFO   {Thread-27}一些短信

     

2010-06-01 06:43:02,803 INFO   {Thread-27}一些短信

     

2010-06-01 06:43:02,804 INFO   {Thread-27}一些短信

     

2010-06-01 06:43:02,804 INFO   {Thread-27}一些短信

     

2010-06-01 06:43:02,809 DEBUG   {Thread-27}一些短信

     

2010-06-01 06:43:02,809 DEBUG   {Thread-27}一些短信

     

2010-06-01 06:43:02,809 DEBUG   {Thread-27}一些短信

     

2010-06-01 07:08:02,809 DEBUG   {Thread-27}一些短信

     

2010-06-01 07:08:02,809 DEBUG   {Thread-27}一些短信

我的目标是找到时间戳在当前时间之前1小时的所有这些行。

如何实现这一目标?

3 个答案:

答案 0 :(得分:4)

DateTime模块非常适合此问题的需要:

use strict;
use warnings;
use DateTime;

my $oneHourAgo = DateTime->now()->subtract( hours => 1 );
my $threshold  = join ' ', $oneHourAgo->ymd, $oneHourAgo->hms;  # Time as string

open my $logFile, '<', 'logfile.txt';

while (my $log = <$logFile>) {

    chomp $log;
    my ($time) = split /,/, $log;       # Gets current log's time

    print $log if $time ge $threshold;  # String-compares log's time to threshold
}

close $logFile;

答案 1 :(得分:1)

由于时间戳将被排序,您可以尝试一种扭曲的Binary Search

由于大多数线条的长度不一样,你可以寻找一定的偏移量,寻找前后出现的换行符(或者你所拥有的任何行终止符)(或者之后的之后),你得到一个候选线。现在将线上的日期与您要查找的日期进行比较,并决定是再次寻找,还是只是环顾这条线。

在确定接下来要寻找的偏移量时,您可以尝试使用与Interpolation Search类似的内容,即根据您获得的线的时间与您搜索的时间之间的差异来确定偏移量。

这应该比线性搜索快得多。

有关使用perl进行二进制搜索的示例:http://perl.plover.com/yak/lightweight-db/materials/slides/slide024.html

答案 2 :(得分:0)

线路输出的顺序是否重要?如果您不介意使用最新的第一个,可以考虑使用File::ReadBackwards。继续向后读,直到一条线超过一个小时,然后停止。如果您希望按特定顺序使用它们,则可以将它们存储在数组中并根据需要进行打印。 (这假定它是一个或多或少的标准日志文件,文件末尾有最新的条目。)

相关问题