Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将一个文件中的两列分开,并将新列中的输出打印到多个文件的同一文件中_Python_Perl_Numpy_Awk - Fatal编程技术网

Python 将一个文件中的两列分开,并将新列中的输出打印到多个文件的同一文件中

Python 将一个文件中的两列分开,并将新列中的输出打印到多个文件的同一文件中,python,perl,numpy,awk,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,

我有很多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(ie 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中的任何其他替代解决方案都将非常好

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

下面是一种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
perl-ne'chomp;如果(/\t[^,]+,(\d+):0*([1-9]\d*)[\S]*$/){$n=$1;$d=$2;打印($\t),$n/$d,“\n”)}其他{print($\t\n”)}result\u 1.new
这就行了。它将确保匹配中的分母([1-9]\d*)为非0正值,并允许在前面加上“0*”的前导零

chomp去掉了硬回车(“\n”),所以它被钉在印刷品上

它确保您正在解析从最后一个选项卡到字符串末尾的最后一列,并允许使用空格

-n将代码包装在while(){…}中

它添加了一个制表符,即使有被零除的情况,但在这种情况下,最后一列为空

如果您想覆盖原始文件,可以在以后对该文件进行mv,但我更喜欢将其保存为备份


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

如果$2不为零,则无论$3是否为零,awk操作都将执行,因此如果为零,则您将从
$2/$3
中得到一个除以零的结果。问题在于你的逻辑,而不是你正在使用的工具;实际上不需要临时文件和管道、cats、cuts和sed,因为awk可以在一个命令中自己完成所有需要的事情。如果你把你的例子简化一点,我相信有人会看一看-现在输入行太长,充满了太多不相关的细节,很多人都不想费心去理解它。请你提出一个替代的解决方案……用awkSure,只需按照我的要求去做,然后编辑你的问题,使用更简单的输入/输出,首先演示你的问题。我看不出为什么我们需要尝试理解一个包含大约20个字段的示例,有些字段有自己的10多个字段——比如说,创建5个字段,每个字段中包含3个子字段。也- IDK如果您显示的输入是“Reult1”或“示例”的内容,请确保您不必将“结果1”显示给“样本”,这将改变字段之间的空白。请考虑编辑您的帖子,以添加更多关于代码的解释以及它为什么会解决问题的解释。一个只包含代码的答案(即使它正在工作)通常不会帮助OP理解他们的问题。脚本给出的错误与之前给出的错误相同..awk:cmd。行:1:(FILENAME=BM\u CR\u pat\u 4.vep FNR=1)致命:尝试零除..感谢您的解决方案,但此Perl one行不会更改结果中的任何内容。新文件不确定我是否理解您的意思。当我在您给出的示例中使用它时,它会在末尾添加一个值为0.6的列。也许您还有其他数据,其最后一列的格式不同?此解决方案要求最后一列包含逗号、数字、冒号和另一个数字(该序列的第一次出现),然后是非空格和行尾的空格。尾随选项卡将破坏此解决方案。所有这些都可以解释,但我必须看到所有的可能性。如果在这个例子中不起作用,我必须看到你试图找出不同之处。