Storing all data in a hash, so this might break down once your files become huge. There is absolutely no error handling in there, so if the file format varies or the entries have spaces in them, it will not work anymore. So please take it as proof of concept and not as production code.
use strict;
use warnings;
sub readfile {
my ( $filename, $hashref, $headref ) = @_;
open my $fh, "<", $filename or die "Cannot open $filename!\n";
my $headers = <$fh>;
my @h = split /\s/, $headers;
$headref->{$_}++ for @h[3..$#h];
while( <$fh> ) {
my @line = split /\s/;
$hashref->{$line[0]}{$line[1]}{$line[2]}{$h[$_]} = $line[$_] f
+or 3..$#h;
}
close $fh;
}
my %joined;
my %headers;
for my $file ( qw/file1.txt file2.txt file3.txt/ ) {
readfile( $file, \%joined, \%headers );
}
print "ID NAME date ", join( " ", sort keys %headers ), "\n";
for my $id ( sort keys %joined ) {
for my $name ( sort keys %{$joined{$id}} ) {
for my $date ( sort keys %{$joined{$id}{$name}} ) {
print "$id $name $date ";
print join " ", map { $joined{$id}{$name}{$date}{$_} // "-
+-" } sort keys %headers;
print "\n";
}
}
}