我有一个日志文件,每行都有一个时间戳,如下所示。我需要在两个日期之间获取数据。例如,在8月9日16:24:23到8月9日16:28:00之间获取数据,即使它们不在文件中。
Aug 9 16:24:21 linux-447z dbus-daemon[685]:
Aug 9 16:24:21 linux-447z dbus[685]: [system] Activating service
Aug 9 16:24:21 linux-447z dbus-daemon[685]:
Aug 9 16:24:21 linux-447z dbus-daemon[685]: dbus[685]: [system]
Aug 9 16:24:21 linux-447z dbus[685]: [system] Successfully activated
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: renewing lease of 192.168.37.128
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: leased 192.168.37.128 for 1800 seconds
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: adding IP address 192.168.37.128/24
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: adding
Aug 9 16:27:47 linux-447z dhcpcd[3422]: eth0: Failed to lookup
Aug 9 16:27:47 linux-447z ifup: eth0
Aug 9 16:27:48 linux-447z SuSEfirewall2:
Aug 9 16:29:03 linux-447z dbus[685]: [system] Activating service
答案 0 :(得分:4)
您可以使用Time::Piece(自Perl 5.10以来的核心模块)进行日期解析和比较:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Time::Piece;
my $format = '%b %e %T';
my $start = Time::Piece->strptime('Aug 9 16:24:23', $format);
my $end = Time::Piece->strptime('Aug 9 16:28:00', $format);
while (<DATA>) {
my ($timestamp) = /(^\w+\s+\d+\s+\d\d:\d\d:\d\d)/;
my $t = Time::Piece->strptime($timestamp, $format);
print if $t >= $start && $t <= $end;
}
__DATA__
Aug 9 16:24:21 linux-447z dbus-daemon[685]:
Aug 9 16:24:21 linux-447z dbus[685]: [system] Activating service
Aug 9 16:24:21 linux-447z dbus-daemon[685]:
Aug 9 16:24:21 linux-447z dbus-daemon[685]: dbus[685]: [system]
Aug 9 16:24:21 linux-447z dbus[685]: [system] Successfully activated
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: renewing lease of 192.168.37.128
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: leased 192.168.37.128 for 1800 seconds
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: adding IP address 192.168.37.128/24
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: adding
Aug 9 16:27:47 linux-447z dhcpcd[3422]: eth0: Failed to lookup
Aug 9 16:27:47 linux-447z ifup: eth0
Aug 9 16:27:48 linux-447z SuSEfirewall2:
Aug 9 16:29:03 linux-447z dbus[685]: [system] Activating service
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: renewing lease of 192.168.37.128
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: leased 192.168.37.128 for 1800 seconds
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: adding IP address 192.168.37.128/24
Aug 9 16:27:46 linux-447z dhcpcd[3422]: eth0: adding
Aug 9 16:27:47 linux-447z dhcpcd[3422]: eth0: Failed to lookup
Aug 9 16:27:47 linux-447z ifup: eth0
Aug 9 16:27:48 linux-447z SuSEfirewall2:
答案 1 :(得分:0)
您可以解析以散列形式存储数据的每一行:将日期转换为int(只为数据样本删除':')并将其用作键,值应为数组,因为您同时拥有多个数据。将边框值转换为数字将帮助您限制结果输出。
答案 2 :(得分:0)
如果您的日志文件中的时间戳具有已知或明确标记的时区,则应该很简单,例如:使用Time :: Piece(以此问题的其他答案为例)或更简单的要求(例如文件中的时间戳和grep在同一时区)Time :: Local。
但是,使用您的示例文件(例如典型的系统日志文件),它会变得毛茸茸,因为您既没有时区信息,也没有年份,如果这些是syslog文件,它们通常使用(但不记录)当前时区,这些时区可以在记录时更改,特别是如果你有夏令时。
我曾经参与过一个项目,其中旧的系统日志格式(例如当前时间既没有时区也没有年份)是必需的。为了确定日志开始的时区和年份,我们在每次旋转后在新文件的顶部放置一个特殊的日志条目。我们还确保每小时至少写一次日志条目,以便我们可以检测到夏令时和返回时间的变化。打破时间戳的大量解决方法:(