【问题标题】:perl file manipulationperl 文件操作
【发布时间】:2012-05-29 20:23:56
【问题描述】:

我有一个包含这些数据的文件 File1

NC_009066   5239    5308    trnA(tgc)   2.10899859667e-09   -
NC_009066   5309    5382    trnN(gtt)   7.03000463545e-10   -
NC_009066   5422    5487    trnC(gca)   7.09999799728e-08   -
NC_009066   5487    5557    trnY(gta)   3.72200156562e-11   -
NC_009066   5549    7097    cox1    291081744.81    +
NC_009066   7109    7180    trnS2(tga)  1.83000043035e-09   -
NC_009066   7183    7256    trnD(gtc)   2.5720000267e-09    +

还有另一个fasta文件File2

> NC_009066,1,0-17045,
GCTATCGTAGCTTAATTAAAGCATAACACTGAAGATGTTAAGATGAACCCTAGAAA

我已将file1 逐行放入一个数组中,然后我可以通过在/\s+/ 上拆分每一行来访问每一列。

for $line(@array){
    @column= split(/\s+/,$line);
    # print $column[5]."\n";

$gene=substr($seq,$column[1],$column[2]);#$seq extracted from File2....}

但我想做的是从第一行取第二列,从第二行取第三列(substr($seq,5239,5382)),然后从第二行取第二列,从第三行取第三列(substr($seq,5309,5487))..... 最好的方法是什么?

【问题讨论】:

  • 我考虑将来自@column 的所需数据放入一维数组中,因此新数组将如下所示 (5239,5308,trna,-,5309,5382,trnN,-...) 所以我在 $new_array[$i],$new_array[$i+5] 上做 substr

标签: arrays algorithm perl file multidimensional-array


【解决方案1】:

首先,请注意split 的默认效果是将$_ 拆分为空白,丢弃前导和尾随空字段。大多数情况下,这就是您想要的,而 split /\s+/ 是不必要的。如果您想对 $_ 以外的变量调用默认拆分,您必须传递一个文本空格,而不是正则表达式,作为模式参数,例如 split ' ', $line

我建议您首先使用map 创建一个仅包含第二列和第三列数据的数组。

然后您可以遍历数据,提取起始值和结束值并将基因拉出序列。

代码如下所示

use strict;
use warnings;

open my $fh, '<', 'f1.txt' or die $!;

my @data = map [ (split)[1,2] ], <$fh>;

my $seq = 'GCTATCGTAGCTTAATTAAAGCATAACACTGAAGATGTTAAGATGAACCCTAGAAA';

for my $i (1 .. $#data) {
  my ($start, $end) = ( $data[$i-1][0], $data[$i][1] );
  my $gene = substr($seq, $start, $end - $start);
  print "$gene\n";
}

请注意,循环是通过索引1(数组的第二个元素)到$#data(最后一个元素)。这是因为循环体将 previous 元素的第一列和当前元素的第二列作为一对,第一列之前没有元素。

另请注意,您可能需要将参数调整为substr,因为我不知道您的索引是从零开始还是从一开始,或者它们是否包含该索引处的字符。

例如,$start = 1; $end = 2substr('ATC', $start, $end - $start); 将返回 T,而您的实际意思是 AATTC

【讨论】:

  • 嗨,我试过这个方法,我认为它有效,但我意识到文件的第一行不在映射数组@data中
  • 这就是我写的代码 open my $fbed, ';#我需要第 1、2、3、5 列
  • 我不明白你的问题。你在用你提取的新数据做什么?如果您从零开始循环,我的代码将不起作用,因为它从 preceding 记录中获取 start 索引,并且在第一个之前没有记录。我建议您更新您的问题,或者最好写一个新问题。
【解决方案2】:

你已经自己弄清楚了一切,你只是错误地使用了substrperldoc -f substr 中的概要说:

substr EXPR,OFFSET,LENGTH

但是你给了它两个偏移量。相反,从另一个偏移量中减去一个偏移量来计算正确的长度参数。

【讨论】:

  • 任何避免使用2个数组的方法,?
  • @daxim:差不多,但问题还需要从不同的记录中获取开始和结束偏移量。
【解决方案3】:

使用二维数组:

for (my $i = 0; $i < scalar(@array); ++$i) {
    $$table[$i] = [ split(/\s+/,$array[$i]) ];
}

# you may put this into a loop
$start = $$table[0][1];
$end = $$table[1][2] - $$table[0][1];
$gene = substr($seq, $start, $end);

另见perllol

【讨论】:

    猜你喜欢
    • 2015-05-31
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多