我有一个类似下面的vcf文件:http://www.1000genomes.org/node/101
下面是来自该站点的示例:
##fileformat=VCFv4.0
##fileDate=20090805
##source=myImputationProgramV3.1
##reference=1000GenomesPilot-NCBI36
##phasing=partial
##INFO=<ID=NS,Number=1,Type=Integer,Description="Number of Samples With Data">
##INFO=<ID=DP,Number=1,Type=Integer,Description="Total Depth">
##INFO=<ID=AF,Number=.,Type=Float,Description="Allele Frequency">
##INFO=<ID=AA,Number=1,Type=String,Description="Ancestral Allele">
##INFO=<ID=DB,Number=0,Type=Flag,Description="dbSNP membership, build 129">
##INFO=<ID=H2,Number=0,Type=Flag,Description="HapMap2 membership">
##FILTER=<ID=q10,Description="Quality below 10">
##FILTER=<ID=s50,Description="Less than 50% of samples have data">
##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
##FORMAT=<ID=GQ,Number=1,Type=Integer,Description="Genotype Quality">
##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Read Depth">
##FORMAT=<ID=HQ,Number=2,Type=Integer,Description="Haplotype Quality">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA00001 NA00002 NA00003
20 14370 rs6054257 G A 29 PASS NS=3;DP=14;AF=0.5;DB;H2 GT:GQ:DP:HQ 0|0:48:1:51,51 1|0:48:8:51,51 1/1:43:5:.,.
20 17330 . T A 3 q10 NS=3;DP=11;AF=0.017 GT:GQ:DP:HQ 0|0:49:3:58,50 0|1:3:5:65,3 0/0:41:3
20 1110696 rs6040355 A G,T 67 PASS NS=2;DP=10;AF=0.333,0.667;AA=T;DB GT:GQ:DP:HQ 1|2:21:6:23,27 2|1:2:0:18,2 2/2:35:4
20 1230237 . T . 47 PASS NS=3;DP=13;AA=T GT:GQ:DP:HQ 0|0:54:7:56,60 0|0:48:4:51,51 0/0:61:2
20 1234567 microsat1 GTCT G,GTACT 50 PASS NS=3;DP=9;AA=G GT:GQ:DP 0/1:35:4 0/2:17:2 1/1:40:3在标题行之后,每行都有包含从第10个字段开始的基因型的字段。第10个字段在NA0001标题下;第11个字段是NA0002基因型,依此类推。我有一个包含123种不同基因型的文件,所以从第10位到133位(NA0001到NA0123)。这些字段中显示的内容可以是0/0、0/1、0/2....比如到8/9。现在我想替换所有不相等的。所以我想保留0/0,1/1,2/2等,用./替换0/1,0/2,1/2,4/5,4/6等。
我想用C脚本来写这段代码。我想过使用sed y/regexp/ regular /,但不知道如何在正则表达式中编写所有这些不相等的值。在文件中的其他位置也可能有这些值,所以实际上只有位置10到133应该被替换。它需要被替换;我将需要文件的其余部分使用新值。
希望它是清楚的。有谁知道怎么做吗?
发布于 2014-12-05 02:10:38
这个正则表达式应该做您想做的事情:用./.:替换匹配项:\s(\d)[|\/](?!\1)\d:
细分:
\s(\d)匹配后跟单个数字的空格,捕获捕获组#1中的数字
[|\/]匹配竖线或斜杠(因为VCF格式似乎允许两者之一)
(?!\1)\d使用负向先行检查来确保下一个字符与捕获组#1不同,并与数字匹配
警告:
我匹配了前导空格和尾随的:,以确保它只与预期的值匹配。我不能想出一个好的方法将它限制在字段10及之后。
使用perl的示例:
perl -pe 's@\s(\d)[|/](?!\1)\d:@ ./.:@g' testfile.vcf > testfile_afterchange.vcf注意:我使用@作为分隔符,以避免转义正则表达式中的/字符。
https://stackoverflow.com/questions/27298628
复制相似问题