Merge Two files of columns but insert columns of second file into columns of first file Merge Two files of columns but insert columns of second file into columns of first file unix unix

Merge Two files of columns but insert columns of second file into columns of first file


You can use a loop in awk, for example

paste file_A file_B | awk '{     half = NF/2;     for(i = 1; i < half; i++)    {        printf("%s %s ", $i, $(i+half));    }    printf("%s %s\n", $half, $NF);}'

or

paste file_A file_B | awk '{     i = 1; j = NF/2 + 1;    while(j < NF)    {        printf("%s %s ", $i, $j);        i++; j++;    }    printf("%s %s\n", $i, $j);}'

The code assumes that the number of columns in awk's input is even.


Use this Perl one-liner after paste to print alternating columns:

paste file_A file_B | perl -F'\t' -lane 'print join "\t", @F[ map { ( $_, $_ + ( @F/2 ) ) } 0 .. ( $#F - 1 ) /  2 ];'

Example:

Create tab-delimited input files:

perl -le 'print join "\t", 1..5 for 1..2;' > file_Aperl -le 'print join "\t", "A".."E" for 1..2;' > file_Bhead file_A file_B

Prints:

==> file_A <==1       2       3       4       51       2       3       4       5==> file_B <==A       B       C       D       EA       B       C       D       E

Paste files side by side, also tab-delimited:

paste file_A file_B | perl -F'\t' -lane 'print join "\t", @F[ map { ( $_, $_ + ( @F/2 ) ) } 0 .. ( $#F - 1 ) /  2 ];'

Prints:

1       A       2       B       3       C       4       D       5       E1       A       2       B       3       C       4       D       5       E

The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-n : Loop over the input one line at a time, assigning it to $_ by default.
-l : Strip the input line separator ("\n" on *NIX by default) before executing the code in-line, and append it when printing.
-a : Split $_ into array @F on whitespace or on the regex specified in -F option.
-F'/\t/' : Split into @F on TAB, rather than on whitespace.

$#F : last index of the array @F with the input fields, split on tab.
0 .. ( $#F - 1 ) / 2 : array of indexes of the array @F, from the start (0) to half of the array. These are all indexes that correspond to file_A.
map { ( $_, $_ + ( @F/2 ) ) } 0 .. ( $#F - 1 ) / 2 : map takes the above array of indexes from 0 to half of the length of @F, and returns a new array, with twice the number of elements. Its elements alternate: (a) the index corresponding to file_A ($_) and (b) that index plus half the length of the array ($_ + ( @F/2 )), which is the corresponding index from file_B.
@F[ map { ( $_, $_ + ( @F/2 ) ) } 0 .. ( $#F - 1 ) / 2 ] : a slice of array @F with the specified indexes, namely alternating fields from file_A and file_B.

SEE ALSO:

perldoc perlrun: how to execute the Perl interpreter: command line switches
perldoc perldata: Slices


With one awk script parsing the files:

FNR==NR {    rec[NR] = $0    next}{    split(rec[FNR], fields)    for (i=1;i<=NF;i++) $i = fields[i] FS $i    print}

Usage:

awk -f tst.awk file_A file_B