我有带时间戳的日志文件。我想使用sed
在两个时间戳之间搜索文本,即使第一个时间戳或最后一个时间戳不存在。
例如,如果我在9:30到9:40之间搜索,那么它应该返回文本,即使9:30和9:40都没有,但时间戳在9:30到9:40之间。
我正在使用sed
一个班轮:
sed -n '/7:30:/,/7:35:/p' xyz.log
但如果两个时间戳都存在,它只返回数据;如果缺少其中一个时间戳,它将打印所有内容。如果时间是12小时格式,它将为AM和PM提取数据。
此外,我对不同的日志文件有不同的时间戳格式,因此我需要一个通用命令。
以下是一些时间格式示例:
<Jan 27, 2013 12:57:16 AM MST> Jan 29, 2013 8:58:12 AM 2013-01-31 06:44:04,883
其中一些包含AM / PM,即12小时格式,其他包含24小时格式,所以我也必须考虑到这一点。
我也试过了,但它不起作用:
sed -n -e '/^2012-07-19 18:22:48/,/2012-07-23 22:39:52/p' history.log
答案 0 :(得分:1)
由于您必须解析严重的时间格式混合,sed
不是正确的工具。我会自动触及Perl,但Python也会这样做,如果你把它放在心上,你可能会在awk
中完成它。你需要规范化时间格式(你没有说日期,所以我假设你只使用时间部分)。
#!/usr/bin/env perl
use strict;
use warnings;
use constant debug => 0;
my $lo = "09:30";
my $hi = "09:40";
my $lo_tm = to_minutes($lo);
my $hi_tm = to_minutes($hi);
while (<>)
{
print "Read: $_" if debug;
if (m/\D\d\d?:\d\d:\d\d/)
{
my $tm = normalize_hhmm($_);
print "Normalized: $tm\n" if debug;
print $_ if ($tm >= $lo_tm && $tm<= $hi_tm);
}
}
sub to_minutes
{
my($val) = @_;
my($hh, $mm) = split /:/, $val;
if ($hh < 0 || $hh > 24 || $mm < 0 || $mm >= 60 || ($hh == 24 && $mm != 0))
{
print STDERR "to_minutes(): garbage = $val\n";
return undef;
}
return $hh * 60 + $mm;
}
sub normalize_hhmm
{
my($line) = @_;
my($hhmm, $ampm) = $line =~ m/\D(\d\d?:\d\d):\d\d\s*(AM|PM|am|pm)?/;
my $tm = to_minutes($hhmm);
if (defined $ampm)
{
if ($ampm =~ /(am|AM)/)
{
$tm -= 12 * 60 if ($tm >= 12 * 60);
}
else
{
$tm += 12 * 60 if ($tm < 12 * 60);
}
}
return $tm;
}
我使用了样本数据:
<Jan 27, 2013 12:57:16 AM MST>
Jan 29, 2013 8:58:12 AM
2013-01-31 06:44:04,883
Feb 2 00:00:00 AM
Feb 2 00:59:00 AM
Feb 2 01:00:00 AM
Feb 2 01:00:00 PM
Feb 2 11:00:00 AM
Feb 2 11:00:00 PM
Feb 2 11:59:00 AM
Feb 2 11:59:00 PM
Feb 2 12:00:00 AM
Feb 2 12:00:00 PM
Feb 2 12:59:00 AM
Feb 2 12:59:00 PM
Feb 2 00:00:00
Feb 2 00:59:00
Feb 2 01:00:00
Feb 2 11:59:59
Feb 2 12:00:00
Feb 2 12:59:59
Feb 2 13:00:00
Feb 2 09:31:00
Feb 2 09:35:23
Feb 2 09:36:23
Feb 2 09:37:23
Feb 2 09:35:00
Feb 2 09:40:00
Feb 2 09:40:59
Feb 2 09:41:00
Feb 2 23:00:00
Feb 2 23:59:00
Feb 2 24:00:00
Feb 3 09:30:00
Feb 3 09:40:00
它产生了我认为正确的输出:
Feb 2 09:31:00
Feb 2 09:35:23
Feb 2 09:36:23
Feb 2 09:37:23
Feb 2 09:35:00
Feb 2 09:40:00
Feb 2 09:40:59
Feb 3 09:30:00
Feb 3 09:40:00
我确信这不是处理的唯一方法;但它似乎有效。
如果您需要进行日期分析,那么您需要使用CPAN中的一个日期或时间操作包来处理问题。上面的代码也硬编码脚本中的时间。您可能希望将它们作为命令行参数处理,这是完全可行的,但不是上面的脚本。