如何基于awk中列的部分字符串匹配来连接两个文件

时间:2016-05-10 09:41:13

标签: awk

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

档案A

chr1   123,aa  aa b c d
chr1   234,dd  a  b c d
chr1   af,345,e aa b c d
chr1   456 a  b c d
....

档案B

xxxx  abcd    chr1   123,dd    aa    c    d    e
yyyy  defg    chr1   aa,345    aa    e    f    g
...

我需要根据fileB中的$ 4和fileA中的$ 2加入这两个文件,所以输出如下:

chr1   123,aa       aa    b    c    d    xxxx    abcd
chr1   234,dd       a     b    c    d    xxxx    abcd
chr1   af,345,e     aa    b    c    d    yyyy    defg
chr1   456          a    b    c    d

我正在尝试使用该解决方案:

awk 'NR==FNR{a[$4]=$1OFS$2;next}{$6=a[$2];print}' OFS='\t' fileb filea

这仅适用于fileA中与$ 2完全匹配的情况。是否有任何解决方案来匹配fileA $ 2中用逗号分隔的字符串?

3 个答案:

答案 0 :(得分:1)

只需存储来自fileB的数据,并在必要时将其连接到fileA:

awk 'FNR==NR {data[$4]=$1 FS $2; next}
     {
      split($2,a,","); 
      if (a[1] in data) {$0=$0 FS data[a[1]]}
     }1' fb fa

测试

$ awk 'FNR==NR {data[$4]=$1 FS $2; next} {split($2,a,","); if (a[1] in data) {$0=$0 FS data[a[1]]}}1' fb fa
chr1   123,aa aa b c d xxxx abcd
chr1   234,dd a  b c d
chr1   345,ee aa b c d yyyy defg
chr1   456 a  b c d

答案 1 :(得分:1)

这假设在fileB中出现的任何给定$ 2的fileA都不能有多个值:

$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR { fileB[$4] = $1 OFS $2; next }
{
    tail = ""
    split($2,fileA,/,/)
    for (i in fileA) {
        if (fileA[i] in fileB) {
            tail = OFS fileB[fileA[i]]
        }
    }
    print $0 tail
}

$ awk -f tst.awk fileB fileA
chr1    123,aa  aa      b       c       d       xxxx    abcd
chr1    234,dd  a       b       c       d
chr1    af,345,e        aa      b       c       d       yyyy    defg
chr1    456     a       b       c       d

鉴于您的新输入/输出,您将需要更多类似的内容(未经测试):

BEGIN { FS=OFS="\t" }
NR==FNR {
    split($4,b,/,/)
    for (i in b) {
        fileB[b[i]] = $1 OFS $2
    }
    next
}
{
    tail = ""
    split($2,a,/,/)
    for (i in a) {
        if (a[i] in fileB) {
            tail = OFS fileB[a[i]]
        }
    }
    print $0 tail
}

答案 2 :(得分:1)

另一个awk

$  awk -v c=',' 'NR==FNR{a[c $4 c]=$1 FS $2; next}
                        {for(k in a) if(c $2 c~k) $(NF+1)=a[k]}1' fileB fileA |
column -t


chr1  123,aa    aa  b  c  d  xxxx  abcd
chr1  234,dd    a   b  c  d
chr1  af,345,e  aa  b  c  d  yyyy  defg
chr1  456       a   b  c  d