perl脚本为每列找出每1分钟(12个值中的最大值)的最大值

时间:2013-04-09 08:24:44

标签: perl awk

我需要在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的新用户,请原谅

1 个答案:

答案 0 :(得分: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更少的内存。