通过匹配前两列将列添加到适当的行

通过匹配前两列将列添加到适当的行

我想使用每个文件的前两列在适当的行(前两列匹配的位置)添加从 fil2、file3 和 file4 到 file1 的附加列。 File2 有三列要添加到 file1,但所有其他文件只有一列要添加,即最后一列。

条目NW_456 44NW_987 75未在 file3 中进行注释,因此丢失。我想在该特定列的输出文件中将其保留为空(实际上没有说“空”)。

例子:

文件1

NW_1234 23
NW_1234 29
NW_1234 778
NW_456 44
NW_987 75
NW_987 98
NW_5000 105
NW_5500 37
NW_5500 900

文件2

NW_1234 23  C   0:0:32:0:0:0    42:0:0:0:0:0
NW_1234 29  C   0:0:28:0:0:0    0:28:0:0:0:0
NW_1234 778 C   0:54:0:0:0:0    0:0:53:0:0:0
NW_456  44  G   0:0:0:45:0:0    59:0:0:0:0:0
NW_987  75  G   0:0:0:60:0:0    55:0:0:0:0:0
NW_987  98  C   0:0:63:0:0:0    0:42:0:0:0:0
NW_5000 105 G   0:0:71:0:0:0    0:50:0:0:0:0
NW_5500 37  G   0:0:0:54:0:0    55:0:0:0:0:0
NW_5500 900 A   43:0:0:0:0:0    0:0:0:37:0:0

文件3

NW_1234 23  DOCK
NW_1234 29  DOCK
NW_1234 778 DOCK
NW_987  98  TFEC
NW_5000 105 MIN
NW_5500 37  LIPG
NW_5500 900 MYC

文件4

NW_1234 23  intron_region
NW_1234 29  intron_region
NW_1234 778 intron_region
NW_456  44  intergenic
NW_987  75  intergenic
NW_987  98  intron_region
NW_5000 105 intron_region
NW_5500 37  intron_region
NW_5500 900 intron_region

输出文件

NW_1234 23  C   0:0:32:0:0:0    42:0:0:0:0:0 DOCK intron_region
NW_1234 29  C   0:0:28:0:0:0    0:28:0:0:0:0 DOCK intron_region
NW_1234 778 C   0:54:0:0:0:0    0:0:53:0:0:0 DOCK intron_region
NW_456  44  G   0:0:0:45:0:0    59:0:0:0:0:0 (empty) intergenic
NW_987  75  G   0:0:0:60:0:0    55:0:0:0:0:0 (empty) intergenic
NW_987  98  C   0:0:63:0:0:0    0:42:0:0:0:0 TFEC intron_region
NW_5000 105 G   0:0:71:0:0:0    0:50:0:0:0:0 MIN  intron_region
NW_5500 37  G   0:0:0:54:0:0    55:0:0:0:0:0 LIPG intron_region
NW_5500 900 A   43:0:0:0:0:0    0:0:0:37:0:0 MYC  intron_region

类似于这个问题:根据第二列的匹配添加列

任何帮助表示赞赏!

答案1

使用制表符作为输出字段分隔符,这可以在每个 UNIX 机器上的任何 shell 中使用任何 awk 来工作:

$ cat tst.awk
BEGIN { OFS="\t";  }
FNR==1 { fileNr++ }
{
    key = $1 OFS $2
    if (NR == FNR) {
        keys[++numKeys] = key
    }
    else {
        sub(/([^[:space:]]+[[:space:]]+){2}/,"")
        $1 = $1
        vals[key,fileNr] = $0
    }
}
END {
    for (keyNr=1; keyNr<=numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s", key
        for (fileNr=2; fileNr<ARGC; fileNr++) {
            printf "%s%s", OFS, vals[key,fileNr]
        }
        print ""
    }
}

$ awk -f tst.awk file1 file2 file3 file4
NW_1234 23      C       0:0:32:0:0:0    42:0:0:0:0:0    DOCK    intron_region
NW_1234 29      C       0:0:28:0:0:0    0:28:0:0:0:0    DOCK    intron_region
NW_1234 778     C       0:54:0:0:0:0    0:0:53:0:0:0    DOCK    intron_region
NW_456  44      G       0:0:0:45:0:0    59:0:0:0:0:0            intergenic
NW_987  75      G       0:0:0:60:0:0    55:0:0:0:0:0            intergenic
NW_987  98      C       0:0:63:0:0:0    0:42:0:0:0:0    TFEC    intron_region
NW_5000 105     G       0:0:71:0:0:0    0:50:0:0:0:0    MIN     intron_region
NW_5500 37      G       0:0:0:54:0:0    55:0:0:0:0:0    LIPG    intron_region
NW_5500 900     A       43:0:0:0:0:0    0:0:0:37:0:0    MYC     intron_region

要将空格改为空白(对于进一步的工具解析来说用处不大),只需通过管道传输到column

$ awk -f tst.awk file1 file2 file3 file4 | column -s$'\t' -t
NW_1234  23   C  0:0:32:0:0:0  42:0:0:0:0:0  DOCK  intron_region
NW_1234  29   C  0:0:28:0:0:0  0:28:0:0:0:0  DOCK  intron_region
NW_1234  778  C  0:54:0:0:0:0  0:0:53:0:0:0  DOCK  intron_region
NW_456   44   G  0:0:0:45:0:0  59:0:0:0:0:0        intergenic
NW_987   75   G  0:0:0:60:0:0  55:0:0:0:0:0        intergenic
NW_987   98   C  0:0:63:0:0:0  0:42:0:0:0:0  TFEC  intron_region
NW_5000  105  G  0:0:71:0:0:0  0:50:0:0:0:0  MIN   intron_region
NW_5500  37   G  0:0:0:54:0:0  55:0:0:0:0:0  LIPG  intron_region
NW_5500  900  A  43:0:0:0:0:0  0:0:0:37:0:0  MYC   intron_region

相关内容