Perl 日期范围问题

Perl 日期范围问题,perl,Perl,我有一个日志文件,它有每行的前几个字符作为时间戳 2010-06-01 04:56:02802调试 {Thread-27}一些文本消息 2010-06-01 04:56:02802调试 {Thread-27}一些文本消息 2010-06-01 04:56:02802调试 {Thread-27}一些文本消息 2010-06-01 04:56:02802调试 {Thread-27}一些文本消息 2010-06-01 05:22:02802调试 {Thread-27}一些文本消息 2010-06-01

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

2010-06-01 04:56:02802调试 {Thread-27}一些文本消息

2010-06-01 04:56:02802调试 {Thread-27}一些文本消息

2010-06-01 04:56:02802调试 {Thread-27}一些文本消息

2010-06-01 04:56:02802调试 {Thread-27}一些文本消息

2010-06-01 05:22:02802调试 {Thread-27}一些文本消息

2010-06-01 05:22:02802调试 {Thread-27}一些文本消息

2010-06-01 05:22:02802调试 {Thread-27}一些文本消息

2010-06-01 05:22:02802调试 {Thread-27}一些文本消息

2010-06-01 06:43:02802信息 {Thread-27}一些文本消息

2010-06-01 06:43:02803信息 {Thread-27}一些文本消息

2010-06-01 06:43:02804信息 {Thread-27}一些文本消息

2010-06-01 06:43:02804信息 {Thread-27}一些文本消息

2010-06-01 06:43:02809调试 {Thread-27}一些文本消息

2010-06-01 06:43:02809调试 {Thread-27}一些文本消息

2010-06-01 06:43:02809调试 {Thread-27}一些文本消息

2010-06-01 07:08:02809调试 {Thread-27}一些文本消息

2010-06-01 07:08:02809调试 {Thread-27}一些文本消息

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


如何实现这一点?

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

由于大多数行的长度都不相同,您可以只寻找某个偏移量,查找出现在前后(或前后)的换行符(或任何一个行终止符),就可以得到一个候选行。现在,将线上的日期与您正在寻找的日期进行比较,然后决定是否再次寻找,或者只是在这条线上的附近环顾四周

在确定下一个要搜索的偏移量时,您可以尝试使用类似的方法,即根据您得到的行时间和正在搜索的时间之间的差异来确定偏移量

这应该比线性搜索快得多

例如,使用perl在文件中执行二进制搜索:

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

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;
使用严格;
使用警告;
使用日期时间;
my$oneHourAgo=DateTime->now()->subtract(小时=>1);
我的$threshold=加入“”,$oneHourAgo->ymd,$oneHourAgo->hms;#时间如弦

打开我的$logFile,“行的输出顺序重要吗?如果你不介意把它们放在最新的第一个,你可以考虑使用。继续向后阅读,直到一行超过一小时,然后停止阅读。如果您希望它们按特定顺序排列,您可以将它们存储在一个数组中,然后以您想要的方式打印它们。(这假设它或多或少是一个标准日志文件,文件末尾有最近的条目。)

这是当前小时、分钟和秒之前的一小时吗?或者,如果当前时间是上午7点,您是否只对上午6点记录的所有条目感兴趣?Perl解决方案往往更关注文本处理。看到OP只是在记录了几行之后,二进制搜索真的值得吗?@Zaid:OP试图使用perl来做这件事真的重要吗?OP从未说过日志文件很小,所以我不知道你从哪里得到的。当然,我确实同意OP的问题实际上可能是试图确定某一行的日志时间,但问题并不清楚。我没有说日志文件很小。我说的是,OP只是在几行之后。OP需求很明确:确定那些时间戳在当前时间一小时内的行。这个问题被标记为
perl
,所以我假设它需要一个perl的答案。。。我不是说你的答案是错的,但我从未见过用二进制搜索方法解决这样的问题,可能是因为必须将整个文件加载到内存中。@Zaid:因为OP只在几行之后,所以二进制搜索是理想的!你不想为了读到其中的三行而读很多行。您可以进行二进制搜索,而不必读取内存中的整个文件!perl支持查找文件,不是吗?@白痴:我很好奇。你能发布一些伪代码(或实际代码)来展示你将如何做吗?+1用于使用
ge
而不是(更昂贵地)转换每个时间戳来计算
DateTime::Duration
对象。。。