my $data = join '', ; my $by_month = {}; while($data =~ /^(\d+).*?(\w+) +(\d+) +(\w+)/mg) { print "Capturing $1 $2 $3 $4\n"; $by_month->{$1}->{$2}->{$4} += $3; } for my $month (1..12) { print "Month: $month\n"; for my $product (qw(Shirts Shoes Caps)) { printf "%7s ", $product; for my $country (qw(Asia Australia UK)) { printf "%6d ", $by_month->{$month}->{$product}->{$country} || 0; } print "\n"; } } __DATA__ 1/2/04 Shirts 32 Australia 1/9/04 Shoes 234 Asia 2/12/04 Caps 109 UK 4/4/04 Shoes 6 Asia 4/4/04 Shirts 12 Australia 5/6/04 Shirts 398 Australia #### Month: 1 Shirts 0 32 0 Shoes 234 0 0 Caps 0 0 0 Month: 2 Shirts 0 0 0 Shoes 0 0 0 Caps 0 0 109 Month: 3 Shirts 0 0 0 Shoes 0 0 0 Caps 0 0 0 Month: 4 Shirts 0 12 0 Shoes 6 0 0 Caps 0 0 0