use IO::All; use Data::Dumper; my @rows = io('sms.csv')->chomp->slurp; # warn Dumper \@rows; my %t; for (@rows) { next unless /^\d{4}-\d{2}-\d{2}/; # eg header row my @data = split /\,/; # warn Dumper \@data; my $code = $data[12]; # warn $code; my $time = $data[-1]; # warn $time; $t{code}{$code}++; $t{time} += $time; } # warn Dumper $t{code}; exit; my %demog = map { chomp; my ($a,$b) = split '\: '; $a => $b; } ; print "$_: $t{code}{$_} [$demog{$_}]\n" for sort { $t{code}{$b} <=> $t{code}{$a} } keys %{ $t{code} }; printf "\naverage time: %.2f seconds for %s rows\n", $t{time} / @rows, scalar @rows; __DATA__ DEMOG-0001: No Match DEMOG-0007: Multiple matches found DEMOG-0017: Superceding NHS number returned DEMOG-0022: NHS Number of response record has been invalidated DEMOG-0040: NHS number not verified DEMOG-0042: NHS Number is not a new style number DEMOG-9999: Generic Spine Service Error SMSP-0000: Success SMSP-0001: Input message validation error SMSP-0002: Response message validation error SMSP-0003: Data returned from local store, Spine unavailable SMSP-9999: Generic Spine Mini Service Provider software failure