Сопоставьте столбец одного файла со столбцом другого с помощью awk, когда второй столбец файла содержит запятые

У меня есть два файла: один большой файл, содержащий варианты генов, с несколькими столбцами, разделенными табуляцией. Столбец, содержащий имена генов, может содержать одно имя или несколько имен, разделенных запятыми (в примере имя гена — 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 и так далее. Поэтому мне нужно что-то, что делает точное совпадение, но игнорирует запятую в столбце имени гена или рассматривает его как разделитель полей или что-то подобное.

Заранее спасибо.


person azule_r    schedule 25.09.2015    source источник
comment
Спасибо, так и сделал.   -  person azule_r    schedule 26.09.2015


Ответы (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
        }
    }
}
person Ed Morton    schedule 25.09.2015
comment
Спасибо, это работает! Могу я спросить, что делает буква «а» в разделении? - person azule_r; 26.09.2015
comment
Это имя массива, который заполняет split(). человек awk и искать split(). Я также собираюсь опубликовать для вас пару альтернатив - может быть хорошим введением в awk, чтобы вы увидели несколько разных способов решения проблемы. Обратите внимание: ни в одном из них не участвует getline! - person Ed Morton; 26.09.2015