Eu usaria o modo de parágrafo do Perl para isso:
#!/usr/bin/env perl
use strict;
use warnings;
my %final_lines; # Data structure to hold the modified lines
my $filename = shift // die "No input file given!\n";
open my $IN,'<',$filename or die "Failed to open $filename for input: $!\n";
PARAGRAPH: {
local $/=""; # Paragraph mode
while(<$IN>){ # Read a new "paragraph"
my @lines = split /\n/;
my @fields = split /\s+/,(shift @lines);
my $line_number =0;
for my $line (@lines){
my @data = split /\s+/,$line;
map {
$final_lines{$fields[$_]}->[$line_number] += $data[$_]
} (0..$#data);
$line_number++;
}
}
}
for my $key (sort { $a <=> $b } keys %final_lines){
local $,=' ';
print STDOUT $key,@{$final_lines{$key}};
print STDOUT "\n";
}
Use assim:
$ /path/to/script input_file > output_file
Este código é testado e deve funcionar bem. Como apontado por @cjm nos comentários, provavelmente levará algum tempo se o seu arquivo de entrada for grande. A etapa com maior probabilidade de levar tempo é o sort
final das chaves.