这对我有用:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
my @maxima;
my $prevmin = "";
sub print_maxima
{
print "@maxima\n" if (scalar(@maxima) > 0);
@maxima = ();
}
while (<>)
{
my(@row) = split;
my($hhmm) = substr $row[1], 1, 5;
if ($hhmm ne $prevmin)
{
print_maxima;
$prevmin = $hhmm;
}
foreach my $col (0..(scalar(@row)-1))
{
$maxima[$col] //= $row[$col]; # Avoid undef values
$maxima[$col] = $row[$col] if ($row[$col] gt $maxima[$col]);
}
}
print_maxima;
给定样本数据的扩展版本,经过精心设计,以便第二分钟的最大值始终严格小于第一分钟的值,除非这些值全为零:
02 11:23:18 03 004 009 009 001 002 002 001 001 001 001 004 000 000 258 258 000 00 4/05/2013
01 11:23:22 01 001 001 001 001 001 001 002 001 001 001 004 000 000 000 000 000 00 4/05/2013
02 11:23:23 01 002 006 012 001 002 002 002 002 002 001 004 000 000 241 241 000 00 4/05/2013
01 11:23:27 01 001 002 005 004 006 001 003 001 001 001 004 000 000 000 000 000 00 4/05/2013
02 11:23:28 01 003 001 002 001 002 001 002 001 001 001 004 000 000 256 257 000 00 4/05/2013
01 11:23:32 01 001 001 001 001 001 001 002 001 001 006 009 000 000 000 000 000 00 4/05/2013
02 11:23:33 02 003 003 015 002 005 002 002 001 001 001 004 000 000 204 205 000 00 4/05/2013
01 11:23:37 02 001 001 001 001 002 001 003 001 001 001 005 000 000 000 000 000 00 4/05/2013
02 11:23:38 01 002 001 009 001 004 009 003 001 001 001 004 000 000 266 267 000 00 4/05/2013
01 11:23:42 01 001 001 000 001 001 001 002 001 001 002 011 000 000 000 000 000 00 4/05/2013
02 11:23:43 01 002 002 009 001 002 001 004 000 002 001 004 000 000 195 195 000 00 4/05/2013
02 11:24:18 03 003 008 009 001 002 002 001 001 001 001 004 000 000 258 258 000 00 4/05/2013
01 11:24:22 01 001 001 001 001 001 001 002 001 001 001 004 000 000 000 000 000 00 4/05/2013
01 11:24:23 01 002 006 012 001 002 002 002 001 001 001 004 000 000 241 241 000 00 4/05/2013
01 11:24:27 01 001 002 005 003 005 001 003 001 001 001 004 000 000 000 000 000 00 4/05/2013
01 11:24:28 01 003 001 002 001 002 001 002 001 001 001 004 000 000 256 257 000 00 4/05/2013
01 11:24:32 01 001 001 001 001 001 001 002 001 001 005 009 000 000 000 000 000 00 4/05/2013
02 11:24:33 02 003 003 014 002 005 002 002 001 001 001 004 000 000 204 205 000 00 4/05/2013
01 11:24:37 02 001 001 001 001 002 001 003 001 001 001 005 000 000 000 000 000 00 4/05/2013
01 11:24:38 01 002 001 009 001 004 008 003 001 001 001 004 000 000 265 266 000 00 4/05/2013
01 11:24:41 01 001 001 000 001 001 001 002 001 001 002 010 000 000 000 000 000 00 4/05/2013
01 11:24:42 01 002 002 009 001 002 001 003 000 001 001 004 000 000 195 195 000 00 4/05/2013
脚本的输出是:
02 11:23:43 03 004 009 015 004 006 009 004 002 002 006 011 000 000 266 267 000 00 4/05/2013
02 11:24:42 03 003 008 014 003 005 008 003 001 001 005 010 000 000 265 266 000 00 4/05/2013
该脚本是一个简单的控制中断报告,基于第二列的 hh:mm 部分。最大值比较利用数据的前导零,使用字符串比较 ( gt
) 而不是数字比较。它扫描所有列,因此它在第 2 列中报告一分钟内的最大时间。
它会与以下相邻的数据线混淆:
01 11:24:41 01 001 001 000 001 001 001 002 001 001 002 010 000 000 000 000 000 00 4/05/2013
01 11:24:42 01 002 002 009 001 002 001 003 000 001 001 004 000 000 195 195 000 00 4/06/2013
请注意,日期部分已更改,因此这些行属于两个不同的日期,但它们会聚合到同一分钟,因为代码不查看日期列。也不清楚您的日期格式是 mm/dd/yyyy 还是 dd/mm/yyyy;任何一个都可能是有效的。最好使用yyyy-mm-dd格式;它是明确的,并自动排序为日期顺序。
它是 Perl — TMTOWTDI(有不止一种方法可以做到)。
循环体foreach my $col
可以替换为:
$maxima[$col] = $row[$col] if (!defined $maxima[$col] || $row[$col] gt $maxima[$col]);
这避免了对 Perl 5.10 的需要(//=
当时添加了运算符)。我怀疑您是否能够衡量性能差异。foreach
控件也可以是简单的for (my $col = 0; $col < scalar(@row); $col++)
;同样,在这种情况下,两者之间没有太多选择,但如果列数很大(数千列),则for
使用的内存将少于foreach
.