(UNTESTED) sub tree_paths { my $tree = shift; # assumes hashref map { my $k = $_; my $v = $tree->{$k}; ref $v ? map( [ $k, @$_ ], tree_paths( $v ) ) : [ $k, $v ] } keys %$tree } # now use it with the OP's $hash hashref print "Count Section Item\n"; for ( sort { $b->[2] <=> $a->[2] # count or $a->[0] cmp $b->[0] # section or $a->[1] cmp $b->[1] # item } tree_paths($hash) ) { my( $section, $item, $count ) = @$_; printf "%5d %7s %7s\n", $count, $section, $item; }