use strict; use warnings; use diagnostics; my $file = "c:\\test.data"; my ($type, $state); my %data; my %states; open (FH, $file) or die "[$file]:[$!]"; while () { ($type, $state) = split (/\|/, $_); if ((defined $type) and (defined $state)) { $type =~ s/^\s*//; $type =~ s/\s*$//; $state =~ s/^\s*//; $state =~ s/\s*$//; $data{$type}->{$state} ++; $states{$state} = 1; } } close (FH); print qq~\n~; print_header (\%states); print_data (\%data, \%states); print "
\n"; ############################################################ sub print_data { ############################################################ my ($data_ref, $states_ref) = @_; foreach my $type (keys %$data_ref) { my $total_for_this_type = 0; print "\n"; print "\t$type\n"; foreach my $state (keys %$states_ref) { $data_ref->{$type}->{$state} or $data_ref->{$type}->{$state} = 0; print "\t", $data_ref->{$type}->{$state}, "\n"; $total_for_this_type += $data_ref->{$type}->{$state}; } print "\t$total_for_this_type\n"; print "\n"; } } ############################################################ sub print_header { ############################################################ my ($states_ref) = @_; print "\n"; print "\tMADE\n"; foreach (keys %$states_ref) { print "\t$_\n"; } print "\tTOTAL\n"; print "\n"; print "\n"; print "\t====\n"; foreach (keys %$states_ref) { print "\t", "=" x length ($_), "\n"; } print "\t=====\n"; print "\n"; }