【问题标题】:Match column of one file to column of another using awk when second file column contains commas当第二个文件列包含逗号时,使用 awk 将一个文件的列与另一个文件的列匹配
【发布时间】:2015-09-25 21:40:36
【问题描述】:

我有两个文件——一个是包含基因变异的大文件,多列由制表符分隔。包含基因名称的列可以包含单个名称,也可以包含多个名称,以逗号分隔(示例中的基因名称为 SAMD11 和 NOC2L):

1   874816  874816  -   T   rs200996316 SAMD11  exonic  ENSG00000187634 frameshift insertion
1   878331  878331  C   T   rs148327885 SAMD11  exonic  ENSG00000187634 nonsynonymous SNV
1   879676  879676  G   A   rs6605067   NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   879687  879687  T   C   rs2839  NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   881918  881918  G   A   rs35471880  NOC2L   exonic  ENSG00000188976 nonsynonymous SNV
1   888659  888659  T   C   rs3748597   NOC2L   exonic  ENSG00000188976 nonsynonymous SNV

第二个文件是基因名称的单列列表,例如:

EVC2
SAMD11
COMT

我想将第二个文件中的基因名称与第一个文件中的基因名称相匹配。我目前正在使用 awk:

awk -F $'\t' 'BEGIN { while(getline <"secondfile.txt") gene[$0]=1; } gene[$7]' firstfile.txt > newfile.txt

但是,这只会打印完全匹配,因此不会打印带有 NOC2L、SAMD11 的行。从上面的示例中,预期的输出将是第一个文件的前四行:

1   874816  874816  -   T   rs200996316 SAMD11  exonic  ENSG00000187634 frameshift insertion
1   878331  878331  C   T   rs148327885 SAMD11  exonic  ENSG00000187634 nonsynonymous SNV
1   879676  879676  G   A   rs6605067   NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   879687  879687  T   C   rs2839  NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976

我希望它仍然进行精确匹配,因为某些基因名称可能相似 - 例如,可能有一个名为 SAMD1 的基因,如果我对此进行模糊匹配,那么我会得到 SAMD1、SAMD11 等等.所以我需要一些完全匹配但忽略基因名称列中的逗号,或将其视为字段分隔符或类似的东西。

提前致谢。

【问题讨论】:

  • 谢谢,已经这样做了。

标签: awk grep delimiter


【解决方案1】:
$ cat tst.awk
NR==FNR { genes[$0]; next }
{
    split($7,a,/,/)
    for (i in a) {
        if (a[i] in genes) {
            print
            next
        }
    }
}

$ awk -f tst.awk secondfile.txt firstfile.txt
1   874816  874816  -   T   rs200996316 SAMD11  exonic  ENSG00000187634 frameshift insertion
1   878331  878331  C   T   rs148327885 SAMD11  exonic  ENSG00000187634 nonsynonymous SNV
1   879676  879676  G   A   rs6605067   NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   879687  879687  T   C   rs2839  NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976

这也可以:

$ cat tst.awk
NR==FNR { genes[$0]; next }
{
    for (gene in genes) {
        if ($7 ~ "(^|,)"gene"(,|$)") {
            print
            next
        }
    }
}

【讨论】:

  • 谢谢你,这行得通!请问拆分中的'a'在做什么?
  • 这是split() 正在填充的数组的名称。 man awk 并查找 split()。我也将为您发布一些替代方案 - 可能是 awk 的一个很好的介绍,让您了解解决问题的一些不同方法。注意 - 它们都不涉及getline
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 2019-11-19
相关资源
最近更新 更多