如何从另一个文件向文件添加多个列

时间:2014-12-11 22:13:08

标签: awk

我有两个文件,如下所示,以制表符分隔:

档案A

chr1   123 aa b c d
chr1   234 a  b c d
chr1   345 aa b c d
chr1   456 a  b c d
....

档案B

chr1   123    aa    c    d    e   ff
chr1   345    aa    e    f    g   gg
chr1   123    aa    c    d    e   hh
chr1   567    aa    z    c    a   ii
chr1   345    bb    x    q    r   kk
chr1   789    df    f    g    s   ff
chr1   345    sh    d    t    g   ll

...

我想基于2个键列“chr1”,“123”从文件B向文件A添加新列,即(前两列是键列)。如果两个文件中的键列匹配,则应将文件B中第7列中的数据添加到文件A中的第3列。

例如(chr1 123)键在文件B中找到两次,因此文件A中的第3列有ff,hh用逗号分隔。如果找不到密钥,则应该输入NA,输出应如下所示: 输出:

chr1   123  ff,hh       aa    b    c    d   
chr1   234    NA        a     b    c    d
chr1   345  gg,kk,ll    aa   b    c    d
chr1   456    NA        a    b    c     d

我使用awk解决方案实现了这个目标

awk -F'\t' -v OFS='\t' 'NR==FNR{a[$1FS$2]=a[$1FS$2]?a[$1FS$2]","$7:$7;next}{$3=(($1FS$2 in a)?a[$1FS$2]:"NA")FS $3}1' fileB fileA

现在,我想添加另一列6和第7列。有人可以建议如何做到这一点吗? 输出如下:

chr1   123  ff,hh    e,e     aa    b    c    d   
chr1   234    NA     NA      a     b    c    d
chr1   345  gg,kk,ll g,r,g   aa   b    c    d
chr1   456    NA      NA     a    b    c     d

由于

1 个答案:

答案 0 :(得分:0)

我的建议是使用另一个数组来跟踪你想要添加的下一个变量,但是为了使代码更具可读性,我制作了一个可执行的awk脚本来概括它:

#!/usr/bin/awk -f

BEGIN { FS="\t"; OFS="\t" }

{ key = $1 FS $2 }

FNR==NR {
    updateArray( a, $7 )
    updateArray( b, $6 )
    next
}

{ $3 = concat( a, concat( b, $3 ) ) }

1

function updateArray( arr, fld ) {
    arr[key] = arr[key]!="" ? arr[key] "," fld : fld
}

function concat( arr, suffix ) {
  return( (arr[key]=="" ? "NA" : arr[key]) OFS suffix )
}

以下是细分:

  • 设置FSOFS
  • 为每行阅读
  • 创建一个全局key
  • 将第一个文件中的数据存储在数组ab中,并通过引用函数updateArray传递它们,并通过值传递字段值
  • 使用本地$3函数
  • 更新concat
  • 使用1
  • 打印更新的行

作为另一种选择,您可以将存储在单个a[key]中的值等于您希望在file B中表示的所有$3字段,并将它们分隔为OFS 。这需要在解析a[key]时每次更改file B时解析和重新组合值,但会使$3创建一个简单的三部分连接。