我使用grep在temporaryF文件和arrayWarning之间返回不匹配的数组
my @c =grep!${{map{$_,1}@temporaryF}{$_},@arrayWarning;
在@c里面有很多行例如:
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
你可以看到ROOT在@c中发生了3次.如何迭代@c以仅输出最新出现的ROOT – > Sun Sep 30 00:10:55光纤通道ROOT
而不是其他重复的行.
所以它会变成:
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
解决方法
注意:这是@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
感觉有点像Schwartzian transform.
单线版
这是一个很好的例子,可以通过一个简单的oneliner和Perl强大的interpreter switches完成一个任务:
$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