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[$_] for 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"; } } }