in reply to looping through an array

Let me apologise straight out for ignoring your existing code, but here is one way to get your desired output, from the data you supply...
#!/usr/bin/perl -w use strict; my %data; my ($src, $dest, $dst_port); while (<DATA>) { chomp; my ($src, $dest, $dst_port) = (split, $_)[5,9,10]; $data{$src}{$dest}{$dst_port}++; } for $src (sort by_ip keys %data) { for $dest (sort by_ip keys %{$data{$src}}) { for $dst_port (sort keys %{$data{$src}{$dest}}) { print "$src $dest $dst_port $data{$src}{$dest}{$dst_port}\ +n"; } } } sub ipto32bit { my ($ip, $c, $d, $e, $f); $ip = shift; ($c,$d,$e,$f) = split(/\./,$ip); return ($c << 24) + ($d << 16) + ($e << 8) + $f; } sub by_ip { ipto32bit($a) <=> ipto32bit($b); } __DATA__ %PIX-4-106023 Deny udp src inside 1.1.1.1 1161 dst outside 3.3.3.3 53 +by access-group inside_access_in %PIX-4-106023 Deny tcp src inside 1.1.1.1 1637 dst outside 4.4.4.4 80 +by access-group inside_access_in # etc... rest omitted for brevity
Which prints..
1.1.1.1 3.3.3.3 53 1 1.1.1.1 4.4.4.4 80 2 1.1.1.1 7.7.7.7 53 1 1.1.1.1 9.9.9.9 443 1 1.1.1.1 9.9.9.9 53 1 1.1.1.1 9.9.9.9 80 1 2.2.2.2 3.3.3.3 80 2 2.2.2.2 4.4.4.4 80 1 2.2.2.2 7.7.7.7 80 2 5.5.5.5 3.3.3.3 1433 1 5.5.5.5 6.6.6.6 161 1 5.5.5.5 6.6.6.6 443 1 5.5.5.5 6.6.6.6 80 1 8.8.8.8 4.4.4.4 80 1 8.8.8.8 6.6.6.6 80 1 10.10.10.10 4.4.4.4 80 1 10.10.10.10 6.6.6.6 80 1

Note that I have used split, because your data seems to be well formed. It may or may not be appropriate in your case. The above is not necessarily a serious suggestion, but is given more in the spirit of TIMTOWTDI :)

Cheers,
Darren :)

Replies are listed 'Best First'.
Re^2: looping through an array
by ikegami (Patriarch) on Apr 25, 2006 at 16:47 UTC

    The following is probably faster (especially for large amounts of data), and it sorts the ports numerically. Your solution oddly sorted them alphabetically.

    sub sort_by_ip { return map { substr($_, 4) } sort map { pack("C4a*", split(/\./), $_) } @_; } my %data; while (<DATA>) { chomp; my ($src, $dest, $dst_port) = (split)[5,9,10]; $data{$src}{$dest}{$dst_port}++; } foreach my $src (sort_by_ip keys %data ) { foreach my $dest (sort_by_ip keys %{$data{$src}} ) { foreach my $dst_port (sort { $a <=> $b } keys %{$data{$src}{$dest}}) { print "$src $dest $dst_port $data{$src}{$dest}{$dst_port}\n"; }}}