将多个文件与特定列中的匹配字段组合到一个文件中

Combining many files with matching fields in particular column to a single file

所以我有 128 个文件,两列。 我想通过第一列中的值匹配它们并将第二列中的值从每个文件添加到单个文件。

我在这里找到了解决方案:

发件人:https://unix.stackexchange.com/questions/159961/merging-2-files-with-based-on-field-match

awk 'FNR==NR{a[]=;next} ( in a) {print ,a[],}' file2 file1

它做我想做的,但是我需要它遍历文件夹中的每个文件。

有没有办法让这个命令循环遍历文件夹中的所有文件,或者有更好的方法吗?

示例: 输入

File 1:
    gene_id normalized_count
    A1BG|1  42.3332
    A1CF|29974  165.6696
    A2BP1|54715 0.0000
    A2LD1|87769 138.1270
    A2ML1|144568    2.7612
    A2M|2   7310.6121
    A4GALT|53947    348.3663
    A4GNT|51146 0.0000


File 2:
    gene_id normalized_count
    A1BG|1  18.2019
    A1CF|29974  129.6194
    A2BP1|54715 2.2063
    A2LD1|87769 65.3116
    A2ML1|144568    0.0000
    A2M|2   3415.8632
    A4GALT|53947    83.2874
    A4GNT|51146 0.0000


File 3:
    gene_id normalized_count
    A1BG|1  8.6285
    A1CF|29974  97.6385
    A2BP1|54715 0.0000
    A2LD1|87769 200.5540
    A2ML1|144568    0.0000
    A2M|2   984.0736
    A4GALT|53947    24.0690
    A4GNT|51146 0.4541

期望的输出

        gene_id normalized_count        
        A1BG|1  42.3332 18.2019 8.6285
        A1CF|29974  165.6696    129.6194    97.6385
        A2BP1|54715 0   2.2063  0
        A2LD1|87769 138.127 65.3116 200.554
        A2ML1|144568    2.7612  0   0
        A2M|2   7310.6121   3415.8632   984.0736
        A4GALT|53947    348.3663    83.2874 24.069
        A4GNT|51146 0   0   0.4541

对于所需的输出,我不关心列标签的最终外观。

同样,我的问题是我必须同时对数百个文件执行此操作才能生成一个文件。

以下是一些其他类似问题的解决方案 https://unix.stackexchange.com/questions/122919/merge-2-files-based-on-all-values-of-the-first-column-of-the-first-file

https://unix.stackexchange.com/questions/113879/how-to-merge-two-files-with-different-number-of-rows-in-shell

但他们只需要对几个文件执行此操作。

编辑:Nathan 和 joepd 都工作并产生了相似的输出 谢谢!

Nathan 的解决方案将产生 space 分隔的输出

joepd 将生成具有 header(原始制表符分隔)的输出,第一列由两个 space 分隔,其余 space 分隔。

您将需要 gawk 为此:

gawk '{a[]+=}; END{ for (i in a) print i, a[i]}' files*

如果这对您不起作用,请指定输入和输出。

编辑

在您指定之后,很明显您想要连接字符串。这个怎么样?

awk '
    NR==1  {title=[=11=]}
    FNR!=1 {a[] = a[]" "}
    END {
        print title
        for (i in a)
            print i, a[i]
    }
' files* 

这应该会产生您想要的输出,并在输入中的每个文件的输出中多一列:

awk 'FNR>2{a[]=a[] " " }; END{ for (i in a) print i a[i]}' File*

它的结构类似于@joepd 的答案,它对输入进行数字求和而不是字符串连接。

FNR>2用于忽略每个文件中的header行。