M
Milkweed
I am trying sort an multi-dimensional array with three elements in
each "row".
Here's a look at a small section of input data:
207.28.198.86 10.36.1.121 0310291642
207.28.198.86 10.36.1.121 0310291753
207.28.201.113 10.77.2.241 0310291642
207.28.200.113 10.75.2.87 0310291642
207.28.199.86 10.76.1.80 0310291642
207.28.198.104 10.1.3.153 0310291642
207.28.198.86 10.36.1.121 0310291324
207.28.199.104 10.2.2.77 0310291642
207.28.195.33 10.2.4.111 0310291642
These are timestamped NAT translations from a firewall.
What I want to do is sort this data by element 0 (global IP) as the
primary key and element 2 (timestamp) as the secondary key so I can
keep a historical record of NAT translations for a given global IP.
I can't seem to get the sort to work. Here is a copy of what I have
tried so far:
#!/usr/bin/perl
use strict;
use warnings;
use Net::Telnet::Cisco;
use Data::Sorting qw( :basics :arrays );
....
foreach (@xlate) { # @xlate is populated by a SNMP call to the
firewall
next unless /^Global/;
my ($global, $local) = (split /\s/)[1,3];
push @entries, [$global,$local,$timestamp];
# each row of @entries now looks like the sample data above
}
#Sort entries by IP (primary key) and date (secondary key) and print
output
my @ordered = sorted_array( @entries,
{ engine=> 'packed', sortkey=>$_[0][0] },
sortkey=>$_[0][2] );
#my $i = 0;
#keys my %h = @history;
#@h{ sort map pack('C4 A x N' => $->[0] =~
/(\d+)\.(\d+)\.(\d+)\.(\d+)/,
# $_->[2], $i++) => @history } = @history;
#my @ordered = @h{ sort keys %h };
open NEW, ">xlate-ordered"
or die "Could not open xlate-ordered for writing: $!\n";
for my $row (@ordered) {
print NEW "@$row\n";
}
As you can see I have tried using the "indexed sort" method from "A
Fresh Look at Efficient Perl Sorting" as well as the Data::Sorting
module with no success. Help with either option would be much
appreciated!
Thanks,
Chris
each "row".
Here's a look at a small section of input data:
207.28.198.86 10.36.1.121 0310291642
207.28.198.86 10.36.1.121 0310291753
207.28.201.113 10.77.2.241 0310291642
207.28.200.113 10.75.2.87 0310291642
207.28.199.86 10.76.1.80 0310291642
207.28.198.104 10.1.3.153 0310291642
207.28.198.86 10.36.1.121 0310291324
207.28.199.104 10.2.2.77 0310291642
207.28.195.33 10.2.4.111 0310291642
These are timestamped NAT translations from a firewall.
What I want to do is sort this data by element 0 (global IP) as the
primary key and element 2 (timestamp) as the secondary key so I can
keep a historical record of NAT translations for a given global IP.
I can't seem to get the sort to work. Here is a copy of what I have
tried so far:
#!/usr/bin/perl
use strict;
use warnings;
use Net::Telnet::Cisco;
use Data::Sorting qw( :basics :arrays );
....
foreach (@xlate) { # @xlate is populated by a SNMP call to the
firewall
next unless /^Global/;
my ($global, $local) = (split /\s/)[1,3];
push @entries, [$global,$local,$timestamp];
# each row of @entries now looks like the sample data above
}
#Sort entries by IP (primary key) and date (secondary key) and print
output
my @ordered = sorted_array( @entries,
{ engine=> 'packed', sortkey=>$_[0][0] },
sortkey=>$_[0][2] );
#my $i = 0;
#keys my %h = @history;
#@h{ sort map pack('C4 A x N' => $->[0] =~
/(\d+)\.(\d+)\.(\d+)\.(\d+)/,
# $_->[2], $i++) => @history } = @history;
#my @ordered = @h{ sort keys %h };
open NEW, ">xlate-ordered"
or die "Could not open xlate-ordered for writing: $!\n";
for my $row (@ordered) {
print NEW "@$row\n";
}
As you can see I have tried using the "indexed sort" method from "A
Fresh Look at Efficient Perl Sorting" as well as the Data::Sorting
module with no success. Help with either option would be much
appreciated!
Thanks,
Chris