#!/usr/bin/perl -w use strict; my %all; open(INPUT,") { if ($_ =~ /^#/) { next } my ($src, $dest, $bytes) = split; # hash of hashes holds the from->to transmission TOTALS; we do not keep all the data $all{$src}{$dest}+=$bytes; } close(INPUT); # simple use of map to create array of references to hashes: my @reflist = map { \%{$all{$_}} } keys %all; # so...create an array of references to arrays (from map callback) of scalars and REFS TO existing hashes and new anonymous arrays! my @reflist = sort { $$b[2] <=> $$a[2] } map buildlist($_), keys %all; # sort by the total of TOTALS foreach my $ref (@reflist) { print "$$ref[0] $$ref[2]\n"; # the next two are the same: foreach my $line (@{$ref->[3]}) { print "\t$line ${$ref->[1]}{$line}\n" } # foreach my $line (@{$$ref[3]}) { print "\t$line ${$$ref[1]}{$line}\n" } } sub buildlist { my $site = $_; my @tmp; $tmp[0]=$site; $tmp[1]=\%{$all{$site}}; foreach (keys %{$tmp[1]}) { $tmp[2]+=${$tmp[1]}{$_} } # make element 3 a reference to an anonymous array of scalars (the dest site names, ranked) @{$tmp[3]} = sort { ${$tmp[1]}{$b} <=> ${$tmp[1]}{$a} } keys %{$tmp[1]}; return \@tmp; # 0=site name, 1=hash ref, 2=total bytes for all transmissions from site, 3=ranked dest names ref } __DATA__ 2000 lines, eg: gilligan.crew.hut lovey.howell.hut 4721 thurston.howell.hut lovey.howell.hut 4046 professor.hut ginger.girl.hut 5768 gilligan.crew.hut laser3.copyroom.hut 9352 gilligan.crew.hut maryann.girl.hut 1180 fileserver.copyroom.hut thurston.howell.hut 2548 skipper.crew.hut gilligan.crew.hut 1259