简体   繁体   English

解析 VCF 文件的 INFO 字段

[英]Parse VCF file's INFO field

Please help me parse a VCF file.请帮我解析一个VCF文件。 I am pasting a real example.我正在粘贴一个真实的例子。

Input:输入:

1   1014143 rs786201005 C   T   .   .   RS=786201005;RSPOS=1014143;dbSNPBuildID=144;SSR=0;SAO=1;VP=0x050068000605000002110100;GENEINFO=ISG15:9636;WGT=1;VC=SNV;PM;PMC;NSN;REF;ASP;LSD;OM;CLNALLE=1;CLNHGVS=NC_000001.11:g.1014143C>T;CLNSRC=OMIM_Allelic_Variant;CLNORIGIN=1;CLNSRCID=147571.0003;CLNSIG=5;CLNDSDB=MedGen:OMIM:Orphanet;CLNDSDBID=C4015293:616126:ORPHA319563;CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification;CLNREVSTAT=no_criteria;CLNACC=RCV000162196.3
1   1014228 rs1921  G   A,C .   .   RS=1921;RSPOS=1014228;dbSNPBuildID=36;SSR=0;SAO=0;VP=0x050328000a0517053f000100;GENEINFO=ISG15:9636;WGT=1;VC=SNV;PM;PMC;S3D;SLO;NSM;REF;ASP;VLD;G5A;G5;HD;GNO;KGPhase1;KGPhase3;CLNALLE=1;CLNHGVS=NC_000001.11:g.1014228G>A;CLNSRC=.;CLNORIGIN=1;CLNSRCID=.;CLNSIG=2;CLNDSDB=MedGen;CLNDSDBID=CN169374;CLNDBN=not_specified;CLNREVSTAT=single;CLNACC=RCV000455759.1;CAF=0.6611,0.3389,.;COMMON=1
1   1014316 rs672601345 C   CG  .   .   RS=672601345;RSPOS=1014319;dbSNPBuildID=142;SSR=0;SAO=1;VP=0x050068001205000002110200;GENEINFO=ISG15:9636;WGT=1;VC=DIV;PM;PMC;NSF;REF;ASP;LSD;OM;CLNALLE=1;CLNHGVS=NC_000001.11:g.1014319dupG;CLNSRC=OMIM_Allelic_Variant;CLNORIGIN=1;CLNSRCID=147571.0002;CLNSIG=5;CLNDSDB=MedGen:OMIM:Orphanet;CLNDSDBID=C4015293:616126:ORPHA319563;CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification;CLNREVSTAT=no_criteria;CLNACC=RCV000148989.5
1   1014359 rs672601312 G   T   .   .   RS=672601312;RSPOS=1014359;dbSNPBuildID=142;SSR=0;SAO=1;VP=0x050068000605000002110100;GENEINFO=ISG15:9636;WGT=1;VC=SNV;PM;PMC;NSN;REF;ASP;LSD;OM;CLNALLE=1;CLNHGVS=NC_000001.11:g.1014359G>T;CLNSRC=OMIM_Allelic_Variant;CLNORIGIN=1;CLNSRCID=147571.0001;CLNSIG=5;CLNDSDB=MedGen:OMIM:Orphanet;CLNDSDBID=C4015293:616126:ORPHA319563;CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification;CLNREVSTAT=no_criteria;CLNACC=RCV000148988.5
1   1020183 rs539283387 G   C   .   .   RS=539283387;RSPOS=1020183;dbSNPBuildID=142;SSR=0;SAO=0;VP=0x050000000a05040026000100;GENEINFO=AGRN:375790;WGT=1;VC=SNV;NSM;REF;ASP;VLD;KGPhase3;CLNALLE=1;CLNHGVS=NC_000001.11:g.1020183G>C;CLNSRC=.;CLNORIGIN=1;CLNSRCID=.;CLNSIG=3;CLNDSDB=MedGen;CLNDSDBID=CN169374;CLNDBN=not_specified;CLNREVSTAT=single;CLNACC=RCV000424799.1;CAF=0.9904,0.009585;COMMON=1
1   1020216 rs764659938 C   G   .   .   RS=764659938;RSPOS=1020216;dbSNPBuildID=144;SSR=0;SAO=0;VP=0x050000000a05040002000100;GENEINFO=AGRN:375790;WGT=1;VC=SNV;NSM;REF;ASP;VLD;CLNALLE=1;CLNHGVS=NC_000001.11:g.1020216C>G;CLNSRC=.;CLNORIGIN=1;CLNSRCID=.;CLNSIG=0;CLNDSDB=MedGen;CLNDSDBID=CN221809;CLNDBN=cancer;CLNREVSTAT=single;CLNACC=RCV000422793.1

And I need an output:我需要一个输出:

1014143 rs786201005 C   T   CLNSIG=5    CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification
1014228 rs1921  G   A,C CLNSIG=2    CLNDBN=not_specified
1014316 rs672601345 C   CG  CLNSIG=5    CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification
1014359 rs672601312 G   T   CLNSIG=5    CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification
1020183 rs539283387 G   C   CLNSIG=3    CLNDBN=not_specified
1020216 rs764659938 C   G   CLNSIG=0    CLNDBN=not_provided

That means print column 2,3,4,5 and then parse last column and print just CLNSIG and CLNDBN .这意味着打印第2,3,4,5列,然后解析最后一列并仅打印CLNSIGCLNDBN Problem is, that those values are not always in the same position.问题是,这些值并不总是处于相同的位置。

My try was:我的尝试是:

awk -v OFS="\t"'{print $2,$3,$4,$5,$8}' input

...and then I have no clue how to get CLNSIG and CLNDBN . ...然后我不知道如何获得CLNSIGCLNDBN

Thank you for any ideas.谢谢你的任何想法。

  1. Pure bash , works by using bash to parse the remaining variables in $h , with parameter tranformation output:bash ,通过使用bash解析$h的剩余变量,并带有参数转换输出:

     while read abcdefgh ; do declare ${h//;/ } printf "%s\\t%-10s\\t%s\\t%s\\t%s\\t%s\\n" $b $c $d $e ${CLNSIG@A} ${CLNDBN@A} done < input

    Output:输出:

     1014143 rs786201005 CT CLNSIG='5' CLNDBN='Immunodeficiency_38_with_basal_ganglia_calcification' 1014228 rs1921 GA,C CLNSIG='2' CLNDBN='not_specified' 1014316 rs672601345 C CG CLNSIG='5' CLNDBN='Immunodeficiency_38_with_basal_ganglia_calcification' 1014359 rs672601312 GT CLNSIG='5' CLNDBN='Immunodeficiency_38_with_basal_ganglia_calcification' 1020183 rs539283387 GC CLNSIG='3' CLNDBN='not_specified' 1020216 rs764659938 CG CLNSIG='0' CLNDBN='cancer'
  2. POSIX shell, grep and printf method: POSIX shell、 grepprintf方法:

     while read abcdefgh ; do printf "%s\\t%-10s\\t%s\\t%s\\t%s\\t%s\\n" $b $c $d $e \\ $( echo "$h" | grep -o 'CLN\\(SIG\\|DBN\\)=[^;]*' ) ; done < input

    Output:输出:

     1014143 rs786201005 CT CLNSIG=5 CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification 1014228 rs1921 GA,C CLNSIG=2 CLNDBN=not_specified 1014316 rs672601345 C CG CLNSIG=5 CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification 1014359 rs672601312 GT CLNSIG=5 CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification 1020183 rs539283387 GC CLNSIG=3 CLNDBN=not_specified 1020216 rs764659938 CG CLNSIG=0 CLNDBN=cancer

With perlperl

$ perl -lane 'print join "\t",(@F[1..4], /(?:CLNSIG|CLNDBN)=[^;]+/g)' ip.txt
1014143 rs786201005 C   T   CLNSIG=5    CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification
1014228 rs1921  G   A,C CLNSIG=2    CLNDBN=not_specified
1014316 rs672601345 C   CG  CLNSIG=5    CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification
1014359 rs672601312 G   T   CLNSIG=5    CLNDBN=Immunodeficiency_38_with_basal_ganglia_calcification
1020183 rs539283387 G   C   CLNSIG=3    CLNDBN=not_specified
1020216 rs764659938 C   G   CLNSIG=0    CLNDBN=cancer
  • -a option to split input on white-space, saved in @F array -a在空白处拆分输入的选项,保存在@F数组中
  • /(?:CLNSIG|CLNDBN)=[^;]+/g will return the CLNSIG and CLNDBN fields /(?:CLNSIG|CLNDBN)=[^;]+/g将返回CLNSIGCLNDBN字段
  • @F[1..4] gives fields 2nd to 5th (index starts from 0 ) @F[1..4]给出第 2 到第 5 个字段(索引从0开始)
  • See http://perldoc.perl.org/perlrun.html#Command-Switches for details on -lane options有关-lane选项的详细信息,请参阅http://perldoc.perl.org/perlrun.html#Command-Switches

It can be done using awk:可以使用 awk 来完成:

script.awk脚本.awk

BEGIN { OFS="\t" }
      { clnsig = clndbn = ""
        if( match( $8, /CLNSIG=[^;]+/ ) ) {
          clnsig = substr( $8, RSTART, RLENGTH )
        }
        if( match( $8, /CLNDBN=[^;]+/ ) ) {
          clndbn = substr( $8, RSTART, RLENGTH )
        }
        print $2, $3, $4, $5, clnsig, clndbn
      }

Or more compact, in case that CLNDBN is always after CLNSIG :或者更紧凑,以防CLNDBN总是CLNSIG之后:

script.awk脚本.awk

BEGIN { OFS="\t" }
    { match($8,/(CLNSIG=[^;]+).*(CLNDBN=[^;]+)/, tmp) 
      print $2,$3,$4,$5, tmp[1], tmp[2]
    }

The function match matches a regular expression.函数match匹配正则表达式。 The first form sets the variables RSTART and RLENGTH so that you can extract the text with substring .第一种形式设置变量RSTARTRLENGTH以便您可以使用substring提取文本。

The second form puts the first subexpression (first parentheses) in the array tmp at pos 1, the second subexpression at pos 2 and so on.第二种形式将第一个子表达式(第一个括号)放在数组tmp中的 pos 1 处,第二个子表达式放在 pos 2 处,依此类推。

The regular expression CLNSIG=[^;]+ matches a literal CLNSIG= followed by a substring up to (but not including) the ;正则表达式CLNSIG=[^;]+匹配文字CLNSIG=后跟一个子字符串,直到(但不包括) ; . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM