запросить файл на основе ввода в bash - PullRequest
0 голосов
/ 24 января 2020

Я хотел бы запросить огромный zip-файл генома c (dbsnp.gz) со следующими столбцами, отформатированными следующим образом:

chr1    196575462   rs115411599 A   G   .   .   RS=115411599;RSPOS=196575462;dbSNPBuildID=132;SSR=0;SAO=0;VP=0x050000080005040436000100;GENEINFO=KCNT2:343450;WGT=1;VC=SNV;INT;ASP;VLD;HD;KGPhase1;KGPhase3;CAF=0.9994,0.000599;COMMON=1

Я хотел бы извлечь столбцы 4 и 5 с помощью запроса первые два столбца или третий (или все три, если он делает это быстрее). столбца 1 + 2 или столбца 3 достаточно, чтобы различить guish этих записей.

Мой входной файл (file.txt) содержит 50+ записей:

chr1:196575462   rs115411599

Я изначально думал об использовании awk и zgrep

for i in $(awk -F'\t' '{print $1}' file.txt); do

'{$i == $(zcat dbsnp.gz | awk -F'\t' {print $1,$2} OFS=":"})' '{print $0}'

done

Это не работает? Должен ли я придерживаться awk? или использовать zgrep?

1 Ответ

2 голосов
/ 24 января 2020

[Обновлено с советами Эда Мортона - спасибо]

Допущения:

  • комбинация столбцов 1 + 2 уникальна в пределах file.txt
  • Столбец 3 является уникальным в пределах file.txt

. Начнем с нескольких примеров файлов данных:

$ cat gene.dat
chr1    196575462   rs115411599 A   G   .   .   RS=115411599;RSPOS=196575462;dbSNPBuildID=132;SSR=0;SAO=0;VP=0x050000080005040436000100;GENEINFO=KCNT2:343450;WGT=1;VC=SNV;INT;ASP;VLD;HD;KGPhase1;KGPhase3;CAF=0.9994,0.000599;COMMON=1
chr2    196575462   rs115411588 A   G   .   .   RS=115411599;RSPOS=196575462;dbSNPBuildID=132;SSR=0;SAO=0;VP=0x050000080005040436000100;GENEINFO=KCNT2:343450;WGT=1;VC=SNV;INT;ASP;VLD;HD;KGPhase1;KGPhase3;CAF=0.9994,0.000599;COMMON=1
chr3    196575462   rs115411577 A   G   .   .   RS=115411599;RSPOS=196575462;dbSNPBuildID=132;SSR=0;SAO=0;VP=0x050000080005040436000100;GENEINFO=KCNT2:343450;WGT=1;VC=SNV;INT;ASP;VLD;HD;KGPhase1;KGPhase3;CAF=0.9994,0.000599;COMMON=1

# go ahead and create a *gz file we can use with zcat:

$ gzip -c gene.dat > gene.dat.gz

$ cat file.txt
chr1:196575462   rs115411599
chr2:196500077   rs115400077
chr3:196500088   rs115400088

One awk решение:

awk '
# for first file, use fields 1+2 and 3 as indexes for our associative arrays

FNR==NR { match1[$1,$2] ; match2[$3] ; next }

# for second file, if fields 1+2 matches an index in the match1[] array then print fields $4/$5; if we found a match then go to next line in file

( ($1,$2) in match1 ) { print $4,$5 ; next }

# for second file, if field 3 matches an index in the match2[] array then print fields $4/$5

(      $3 in match2 ) { print $4,$5 }

  # for our first file we will replace : with <space> ; this gives us 3 fields from first file
  # for our second file we will feed the results of the zcat operation
' <(sed 's/:/ /g' file.txt) <(zcat gene.dat.gz)

И результат выполнения вышеуказанного:

A G

A большое преимущество этого подхода состоит в том, что мы сканируем каждый файл только ONCE (например, пример кода в вопросе показывает zcat dbsnp.gz, выполняемый / сканируемый несколько раз внутри while l oop).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...