合并两个列文件,但将第二个文件的列插入第一个文件的列

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

假设两个文件的列数相同。

file_A:

1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

file_B:

A B C D E
A B C D E
A B C D E
A B C D E
A B C D E

我想按顺序合并两个文件

file_C:

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

我在社区中找到了这样的解决方案

paste file_A file_B | awk '{print ,,,,,,,,,}'

但考虑到每个文件的列数大约为 100 或不是常量,我想知道是否有更好的方法。

提前致谢。

paste 之后使用此 Perl one-liner 打印交替列:

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

示例:

创建 tab-delimited 个输入文件:

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

打印:

==> file_A <==
1       2       3       4       5
1       2       3       4       5

==> file_B <==
A       B       C       D       E
A       B       C       D       E

并排粘贴文件,也tab-delimited:

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

打印:

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

Perl one-liner 使用这些命令行标志:
-e :告诉 Perl 查找代码 in-line,而不是在文件中。
-n :一次循环输入一行,默认分配给 $_
-l : 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"),并在打印时附加它。
-a : 在空格或 -F 选项中指定的正则表达式上将 $_ 拆分为数组 @F
-F'/\t/' : 在 TAB 上拆分为 @F,而不是在空格上。

$#F : 包含输入字段的数组 @F 的最后一个索引,在选项卡上拆分。
0 .. ( $#F - 1 ) / 2 : 数组 @Findexes 的数组,从开始 (0) 到数组的一半。这些都是对应file_A.
的索引 map { ( $_, $_ + ( @F/2 ) ) } 0 .. ( $#F - 1 ) / 2 : map 采用上述索引数组从 0 到 @F 长度的一半,returns 一个新数组,元素数量是其两倍。它的元素交替出现:(a) 对应于 file_A ($_) 的索引和 (b) 该索引加上数组长度的一半 ($_ + ( @F/2 )),这是来自的对应索引file_B.
@F[ map { ( $_, $_ + ( @F/2 ) ) } 0 .. ( $#F - 1 ) / 2 ] :具有指定索引的数组 @F 的切片,即来自 file_Afile_B.

的交替字段

另请参见:

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

您可以在 awk 中使用循环,例如

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);
}'

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);
}'

代码假定 awk 输入中的列数是偶数。

用一个 awk 脚本解析文件:

FNR==NR {
    rec[NR] = [=10=]
    next
}

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

用法:

awk -f tst.awk file_A file_B