Этот код Perl принимает все объединяемые файлы и определяет общий заголовок из заголовков всех файлов, а затем изменяет порядок печати столбцов на вывести файлы.
perl -wMstrict -Mvars='*ARGV_orig,*comm_hdr,*prev,*h' -lne '
BEGIN{
@::ARGV_orig = @ARGV;
$::prev = q//;
sub trim {
my ($str) = @_ ? @_ : $_;
for($str) {
s/^\s*//;s/\s*$//;
}
return $str;
}
sub intersection(\@\@) {
@{$_[0]} > @{$_[1]} and @_ = reverse @_;
my @smaller = @{ +shift };
my @larger = @{ +shift };
my @common;
for my $e (@smaller) {
push @common, $e
if grep { $_ eq $e } @larger;
}
return @common;
}
sub col_print_order {
my @common_hdr = @{ $_[0]->{common_header} };
my @header2prn = @{ $_[0]->{header_2print} };
my @reorder;
for my $e (@common_hdr) {
if ( -1 < (my ($l) = grep { $header2prn[$_] eq $e } 0..$#header2prn) ) {
push @reorder, $l;
}
}
return @reorder;
}
}
if ( $ARGV ne $::prev ) {
$::h{$ARGV}{header} = $_;
my @A = split;
@::comm_hdr = @::comm_hdr ? intersection(@::comm_hdr, @A) : @A;
$::prev = $ARGV;
} else {
push @{ $::h{$ARGV}{data} }, $_;
}
END{
local $, = chr(32);
my @comm_hdr_sorted = sort @::comm_hdr;;
print @comm_hdr_sorted;
for my $argv (@::ARGV_orig) {
my @current_header = split /\s+/, trim $::h{$argv}{header};
my @order = col_print_order({
common_header => \@comm_hdr_sorted,
header_2print => \@current_header,
});
my @file = @{ $::h{$argv}{data} };
for my $line_num ( 0..$#file ) {
my $line = trim $file[$line_num];
my @fields = split /\s+/, $line;
print @fields[ @order ];
}
}
}
' yourfile1 yourfile2 yourfile3 # ... specify all your filenames to be merged here
Col1 Col3 Col4 Col5
A C D E
P R Q S