Perl - compares array elements sentences with a variable
arrays, grep, perl
Solution
Note: this is an extension of the answer of @RobEarl - so if you like it, please make sure to give him credits, too!
The point here is to store the line count too, to make sure the output can be ordered.
Long version
#!/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
Output:
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
Feels a little bit like the Schwartzian transform.
One-liner version
This is an excellent example for a task that can be accomplished by a simple oneliner with perl's powerful 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
Output:
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
Problem
I use grep to return unmatched array between temporaryF file and arrayWarning ``` my @c =grep!${{map{$_,1}@temporaryF}{$_},@arrayWarning; ``` Inside @c there are alot of lines for example: ``` 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 ``` as you can see ROOT occurs 3 times in @c. How can I iterate through @c to output only the latest occurrence of ROOT -> Sun Sep 30 00:10:55 fibre channel ROOT and not the other repeated lines. so it will become: ``` 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 ```