Não é tão fácil quanto parece. Solução Perl, tentei ser um pouco mais detalhado para tornar o código compreensível. O conhecimento básico de estruturas de dados aninhadas (hashes de hashes, hashes de matrizes) é necessário.
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my (%collapsed, %groups);
<>; # Skip header.
while (<>) {
my ($line, $group, $name, $value) = split;
push @{ $collapsed{$line}{$group}{names} }, $name;
push @{ $collapsed{$line}{$group}{values} }, $value;
undef $groups{$group};
}
for my $group (sort keys %groups) {
for my $line (sort keys %collapsed) {
next unless $collapsed{$line}{$group};
my $value = join q(), @{ $collapsed{$line}{$group}{values} };
$groups{$group}{$value} ||= keys %{ $groups{$group} };
}
}
for my $group (sort keys %groups) {
for my $line (sort keys %collapsed) {
next unless $collapsed{$line}{$group};
my $value = join q(), @{ $collapsed{$line}{$group}{values} };
say join "\t", $line, $group,
join(' ', @{ $collapsed{$line}{$group}{names} }),
join(' ', @{ $collapsed{$line}{$group}{values} }),
chr $groups{$group}{$value} - 1 + ord 'A',
$groups{$group}{$value},
}
}