我有一个包含以下示例文本的文件。(实际文本很大)。
2014/05/08-19:15:44.544824-<String1>
2014/05/08-19:21:54.544824-<String2>
2014/05/08-19:34:59.564461-<String3>
我必须提取两个时间戳之间的数据,如19:15:00 - 19:20:00等,直到eof。我试过使用sed &好的,但问题是,在某些时候,他们会给出所有的东西。(例如,他们会在19:15:00 -> EOF期间发放所有东西)。我使用的命令是
awk '/19:15:00/,/19:20:00/' InputFile
和
sed '/19:15:00/,/19:20:00/p' Inputfile.
关于如何在perl或sed &哦,哪一种可能真的有用呢?错误的输出与时间戳的格式有关吗?(想)
p。我使用下面的代码来制作时间戳。(是否可能因为localtime函数而发生这种情况?
$curr = timelocal(0, 0, 0, (split ///, $ARGV[0])[1], (split ///, $ARGV[0])[0]-1, (split ///, $ARGV[0])[-1]);
$currentTime = strftime "%H:%M:%S", localtime($curr);
使用perl一行程序。捕捉时间,然后进行比较。
perl -ne '$t = /(d+:[d:.]+)/ ? $1 : undef;
print if $t ge "19:15:00" && $t le "19:20:00";' file.txt
您上面显示的awk和sed命令将不起作用,因为它们正在进行模式匹配—它们不会按时间顺序比较时间戳(即,如果它没有看到精确的19:20:00字符串,即使它在路上看到19:21:00,它也会继续到最后)。
您可能可以在perl中使用类似于您在最后显示的生成时间戳的两行代码来完成它,但是反过来解析它们,将它们转换为时间对象并比较它们的值。
这可能不太明显,但是具有固定宽度字段的日期/时间表示(如ISO 8601 %Y-%m-%dT%H:%M:%S
)可以简单地将其作为字符串进行比较,因此'19:21:54.544824' gt '19:20'
为true,而19:15:44.544824 lt '19:15'
为false。
这意味着您可以只使用split
提取字段并进行文字比较,如下所示
use strict;
use warnings;
while (<DATA>) {
my $time = (split /-/)[1];
print if $time ge '19:15' and $time le '19:20';
}
__DATA__
2014/05/08-19:15:44.544824-<String1>
2014/05/08-19:21:54.544824-<String2>
2014/05/08-19:34:59.564461-<String3>
2014/05/08-19:15:44.544824-<String1>
为什么这么复杂?
$ awk -F'[-.]' '"19:15:00"<=$2 && $2<="19:20:00"' file
2014/05/08-19:15:44.544824-<String1>
或可读性较差,但如果文件排序更有效:
$ awk -F'[-.]' '$2>"19:20:00"{exit} $2>="19:15:00"' file
2014/05/08-19:15:44.544824-<String1>
使用awk
awk '{gsub(/:/,X,$2)}$2>=191500&&$2<=192000' FS="[-.]" file