use 5.010; use List::MoreUtils qw< part >; say for map { my $x = $_; sprintf( '%s %d,%d', $x->[0][0], scalar(grep { $_->[1] eq '1_x' } @$x), scalar(grep { defined $_->[2] } @$x), ) } part { # me thinks List::MoreUtils needs a way to make this simpler state $part = 0; state $last = undef; $part++ if defined $last && $last ne $_->[0]; $last = $_->[0]; $part } map { chomp; [split /\s+/] } sort ; __DATA__ A 1_x 9_z A 1_x A 1_x g_z B 2_c B 1_x 1_z C 1_x 1_z C v_x 8_z