use strict; use warnings; my %site_length_catch; my $max = 0; foreach (@file) { chomp; my @r = split /\t/; # cleaning from your second loop $r[13] =~ s/\D\.\D([0-9]+)\D/$1/; $r[13] =~ s/(\*|\?|s\d+)//; $site_length_catch{$r[0]}{$r[13]}++; $max = $r[13]>$max?$r[13]:$max; } foreach my $gene (keys %site_length_catch) { print $site_length_catch{$gene}{$_} // 0, "\t" for 1..$max; print "\n"; }