2014-12-04 3 views
1

У меня есть 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 и т. Д. На ./.

Я хотел бы написать это в сценарии С. Мысль об использовании sed y/regexp/replacement /, но не знаю, как писать все эти неравные значения в регулярном выражении. И на других позициях в файле также могут быть эти значения, поэтому на самом деле нужно заменить только позиции от 10 до 133. И его нужно заменить; Мне понадобится остальная часть файла с новыми значениями.

Надеюсь, что это ясно. Кто-нибудь знает, как это сделать?

+0

Вы говорите, что хотите заменить что-то вроде '0/1' на литерал' ./. '(Период, косая черта, период)? –

+0

Да, это то, что я хочу сделать – user4311883

ответ

0

Это регулярное выражение должно делать то, что вы хотите: \s(\d)[|\/](?!\1)\d: Заменить матчи с ./.:

Разбивка:

\s(\d) соответствует пробел, затем одну цифру, захватывая цифру в захвата группы № 1

[|\/] соответствует трубе или косе (так как кажется, что формат VCF позволяет либо)

(?!\1)\d использует отрицательный предпросмотр, чтобы гарантировать, что следующий символ не является такой же, как группа захвата # 1, и соответствует цифре,

Предостережения:

Я совпавших ведущее место и отставая :, чтобы попытаться обеспечить он соответствует только заданным значениям. Я не мог разработать хороший способ ограничить его полями 10 и после.

Пример использования Perl:

perl -pe '[email protected]\s(\d)[|/](?!\1)\d:@ ./.:@g' testfile.vcf > testfile_afterchange.vcf 

Примечание: Я использовал @ в качестве разделителя, чтобы избежать того, чтобы избежать / символов в регулярном выражении.

+0

Итак, я набираю это: cat testfile.vcf | sed 'y/\ s (\ d) [| \ /] (?! \ 1) \ d:/\ ./ \ ./> testfile_afterchange.vcf, но я получаю ошибку sed: -e выражение # 1, char 26 : строки для команды «y» имеют разную длину. Поэтому я также пробовал его с помощью «s/old/new /», но не работает, char 28: неверная обратная ссылка. Что я делаю не так? – user4311883

+0

@ user4311883: У вас есть несколько проблем с попыткой использовать 'sed'. Команда 'y' является преобразованием, а не заменой регулярного выражения, поэтому вам нужно использовать' s'. sed regex не поддерживает '\ d' (вместо этого используйте' [0-9] '). Кроме того, в sed, parens для группировки необходимо избегать. Тем не менее, шоу-стоппер заключается в том, что sed не поддерживает поисковые запросы.Я добавлю решение perl к моему ответу, надеясь, что вы можете использовать perl вместо этого. –

+0

Скрипт работает на половину. Я рассчитываю результат на комбинацию значений. Для тестового файла результат выглядит следующим образом: 1408: ./. 3596: 0/0 746: 0/1 31: 0/2 1: 0/3 2: 0/4 2518: 1/1 20: 1/2 67: 2/2 5: 3/3 2: 4/4 1: 6/6, и теперь результат testfile_afterchange выглядит так: 614: ничего не имеет, просто пустое пространство 1194: ./. 4491: 0/0 2041: 1/1 56: 2/2 1: 3/3. Таким образом, общее количество для обоих файлов по-прежнему остается неизменным, ничего не теряется, но не равные, похоже, изменились на пустое пространство и на некоторые из равных. Есть идеи? – user4311883

Смежные вопросы