0

我需要在 12 个值中每 1 分钟找到每列的最大值意味着日志将每 5 秒出现一次,所以每 1 分钟我需要找到每列的最大值

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

需要第 3 到第 14 列的最大值,我是 perl 新手,请见谅

4

1 回答 1

2

这对我有用:

#!/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.

于 2013-04-09T13:16:00.197 回答