如何使用perl计算UCSC摆动文件的逆log2比率?

时间:2015-01-27 15:15:08

标签: perl awk

我有两个单独的文件,即A& B包含相同的标题行,但分别包含2和1列。我想在单独的文件中取第二列或第一列的逆log2,但保持其他描述不变。我有这样的事情..文件A $ 1和$ 2中的值由分隔符标签分隔  文件A

track type=wiggle_0 name=rep1.bar.wig description=GSM1076_rep1.bar.wig graphType=bar  
variableStep chrom=chr1  
12  0.781985  
16  0.810993  
20  0.769601  
24  0.733831  

档案B

track type=wiggle_0 name=rep1.bar.wig description=GSM1078_rep1.bar.wig graphType=bar
variableStep chrom=chr1  
0.721985  
0.610993  
0.760123  
0.573831  

我期待这样的输出。 文件A

track type=wiggle_0 name=rep1.bar.wig description=GSM1076_rep1.bar.wig graphType=bar  
variableStep chrom=chr1  
12  1.7194950944  
16  1.754418585  
20  1.7047982296  
24  1.6630493726  
track type=wiggle_0 name=rep1.bar.wig description=GSM1076_rep1.bar.wig  graphType=bar  
variableStep chrom=chr2 
文件B的

(此文件中的值只是文件A的复制粘贴)

track type=wiggle_0 name=rep1.bar.wig description=GSM1078_rep1.bar.wig  graphType=bar  
variableStep chrom=chr1   
1.7194950944  
1.754418585  
1.7047982296  
1.6630493726  
track type=wiggle_0 name=rep1.bar.wig description=GSM1078_rep1.bar.wig rep1.bar.wig graphType=bar  
variableStep chrom=chr2

3 个答案:

答案 0 :(得分:2)

此awk脚本执行您想要的计算:

awk '/^[0-9.[:space:]]+$/{$NF=sprintf("%.12f", 2^$NF)}1' file

这匹配仅包含数字,句点和任何空格字符的行,将最后一个字段$NF的值替换为2 $NF的幂。可以修改格式说明符%.12f以提供所需的小数位数。最后的1{print}的缩写。

在新文件上测试它:

$ awk '/^[0-9.[:space:]]+$/{$NF=sprintf("%.12f", 2^$NF)}1' A   
track type=wiggle_0 name=rep1.bar.wig description=GSM1076_rep1.bar.wig graphType=bar  
variableStep chrom=chr1  
12 1.719495094445
16 1.754418584953
20 1.704798229573
24 1.663049372620
$ awk '/^[0-9.[:space:]]+$/{$NF=sprintf("%.12f", 2^$NF)}1' B
track type=wiggle_0 name=rep1.bar.wig description=GSM1078_rep1.bar.wig graphType=bar
variableStep chrom=chr1  
1.649449947457
1.527310087388
1.693635012985
1.488470882686

答案 1 :(得分:0)

所以这是Perl版本:

use strict;
open IN, $ARGV[0];
while (<IN>) {
  chomp;  
  if (/^(.*)[\t ]*(-?\d\.\d*)/) { # format "nn m.mmmmm"
    my $power = 2 ** $2;
    print("$1\t" . $power . "\n");
  } elsif (/^(-?\d\.\d*)/) { # format "m.mmmmm"
    my $power = 2 ** $1;
    print($power . "\n");
  } else { # echo all other stuff
    print;
    print ("\n");
  }
}
close IN;

如果您运行<file>.pl <datafile>(替换为适当的名称),它将转换一个文件,使行具有2 **&lt; 2nd value&gt;)。它只是回显了与数字模式不匹配的行。

答案 2 :(得分:0)

  

这是@ThomasKilian的修改后的小脚本   感谢他提供框架。

use strict;
    open IN, $ARGV[0];
    while (<IN>) {
      chomp;  
      if (/^(\d*)[\t ]*(-?\d\.\d*)/) { # format "nn m.mmmmm"
        my $power = 2 ** $2;
        $power= sprintf("%.12f", $power);
        print("$1\t" . $power . "\n");
      } elsif (/^(-?\d\.\d*)/) { # format "m.mmmmm"
        my $power = 2 ** $1;
        $power= sprintf("%.12f", $power);
        print($power . "\n");
      } else { # echo all other stuff
        print;
        print ("\n");
      }
    }
    close IN;