注意:这是@RobEarl 答案的延伸——所以如果你喜欢它,请确保也给他点赞!
这里的要点也是存储行数,以确保可以订购输出。
长版
#!/usr/bin/perl
use strict;
use warnings;
# store (with count)
my $count = 0;
my %latest = map {
my $source = (split /\s+/ => $_)[6];
$source => {count => $count++, string => $_};
} <DATA>;
# output
print $_->{string} for sort {$a->{count} <=> $b->{count}} values %latest;
__DATA__
Sun Sep 30 00:05:55 fibre channel DENY forever
Sun Sep 30 00:06:55 fibre channel ROOT cause
Sun Sep 30 00:08:55 fibre channel ROOT cause
Sun Sep 30 00:10:55 fibre channel ROOT cause
Sun Sep 30 00:20:55 fibre channel DANN
Sun Sep 30 00:30:55 fibre channel DANN
输出:
Sun Sep 30 00:05:55 fibre channel DENY forever
Sun Sep 30 00:10:55 fibre channel ROOT cause
Sun Sep 30 00:30:55 fibre channel DANN
感觉有点像施瓦茨变换。
单线版
这是一个很好的例子,可以通过简单的 oneliner 和 perl 强大的解释器开关来完成:
$ perl -nale '$l{$F[6]}={c=>$c++,s=>$_};END{print$_->{s}for sort{$a->{c}<=>$b->{c}}values%l}'
Sun Sep 30 00:05:55 fibre channel DENY forever
Sun Sep 30 00:06:55 fibre channel ROOT cause
Sun Sep 30 00:08:55 fibre channel ROOT cause
Sun Sep 30 00:10:55 fibre channel ROOT cause
Sun Sep 30 00:20:55 fibre channel DANN
Sun Sep 30 00:30:55 fibre channel DANN
输出:
Sun Sep 30 00:05:55 fibre channel DENY forever
Sun Sep 30 00:10:55 fibre channel ROOT cause
Sun Sep 30 00:30:55 fibre channel DANN