在文件中划分两列并将新列中的输出打印到多个文件的同一文件中

时间:2015-09-29 13:51:12

标签: python perl numpy awk

我有许多VCF格式的文件。这就是它的样子

1   127573  rs7 G   A   79.78   .   AC=1;AF=0.500;AN=2;BaseQRankSum=1.231;ClippingRankSum=-0.358;DB;DP=5;FS=3.979;MLEAC=1;MLEAF=0.500;MQ=60.00;MQ0=0;MQRankSum=0.358;QD=15.96;ReadPosRankSum=1.231  GT:AD:DP:GQ:PL  0/1:2,3:5:27:108,0,27

其中我需要划分最后一列的第二部分并在新列中打印输出..即,从上面的例子中,它的3和5(从第10列0/1:2,3:5: 27:108,0,27)和它应该看起来的输出,即0.6(即3/5)作为最后一列

 1  127573  rs7 G   A   79.78   .   AC=1;AF=0.500;AN=2;BaseQRankSum=1.231;ClippingRankSum=-0.358;DB;DP=5;FS=3.979;MLEAC=1;MLEAF=0.500;MQ=60.00;MQ0=0;MQRankSum=0.358;QD=15.96;ReadPosRankSum=1.231  GT:AD:DP:GQ:PL  0/1:2,3:5:27:108,0,27 0.6

为了达到这个目的,我在unix中使用了awk,如下所示,

cat result_1 |cut -f10 | sed 's/:/\t/g' >sample
cat sample | cut -f2 | sed 's/,/\t/g' | awk '$2!=0 || $3!=0{print $1"\t"$2"\t"$2/$3}' >result_1 

但它抱怨为

awk: (FILENAME=- FNR=1) fatal: division by zero attempted

Python或Perl中的任何其他替代解决方案都会很棒.. !!!

2 个答案:

答案 0 :(得分:3)

awk '{split($NF, a, /[,:]/); $(++NF) = a[3]/a[4]; print}' file

好的,除以零:

awk '{split($NF, a, /[,:]/); $(++NF) = (a[4]==0 ? "Inf" : a[3]/a[4]); print}' file

答案 1 :(得分:1)

这是一种perl方式:

perl -ne 'chomp;if(/\t[^, ]+,(\d+):0*([1-9]\d*)[\S ]*$/){$n=$1;$d=$2;print("$_\t",$n/$d,"\n")}else{print("$_\t\n")}' < result_1 > result_1.new

这样做。它将确保匹配中分母的非0正值([1-9] \ d *),并允许使用&#39; 0 *&#39;在它面前。

chomp删除了硬回车(&#34; \ n&#34;),因此在印刷品中添加了它。

它确保您解析从最后一个标签到字符串末尾的最后一列,并且它允许空格。

-n将代码包装在while(){...}。

它会添加一个标签,即使存在除零,但在这种情况下,将最后一列留空。

如果要覆盖原始文件,可以在以后复制文件,但我更喜欢将前体保存为备份。

在perl或其他语言中可能存在更简洁/可读的方式,但这就足够了。