从文本文件中过滤掉适合perl中任何数组元素的行

时间:2014-10-09 14:33:38

标签: arrays regex perl

我有以下任务要做,我想知道如何在Perl中最有效地解决这个问题。 首先,我有一个包含66个元素的数组(染色体:start:end),看起来像这样

   my @array = qw( chr1:1566-1762  chr7:1695-1955 ....)

接下来,我有一个包含此内容的大小为50MB的文件

   CHR \t START \t \END \tab \Pattern
   chr1 \t 1757 \t \2354 \t XM:Z:......H..H....H
   .
   .

我想检查我的文件的每一行,无论位置,开始和结束是否适合我的数组中的任何元素。文件中读取的位置与我的数组中的位置不同,但开始应包含在范围内。例如,我有一个适合第一个元素的读取" chr1:1566-1662"通过在1757年开始的位置。

你的方法是什么?我对每一个暗示和想法感到高兴!

1 个答案:

答案 0 :(得分:1)

首先,我会将数组从字符串数组更改为某种结构数组(哈希)。这使得一些事情变得更容易:

my @array = (
  { chr => "chr1", start => 1566, end => 1762 },
  { chr => "chr7", start => 1695, end => 1955 }
);

进一步的优化可能是可以想象的(使用染色体作为范围列表的散列中的关键字)。

然后逐行浏览您的文件并拆分每一行并使用此信息进行检查。

open FILE, fname || die "could not open file\n";

while(my $line = <FILE>){
  my @fields = split("\t", $line);
  chomp($fields[0]);  # remove whitespaces
  my $entry = {chr => $fields[0], start => $fields[1], end => $fields[2]};
  foreach $elem(@array){
    if(testMatch($entry, $elem)){
      print "found something";
    }
  }
}

close FILE;

分裂可能更复杂。你在问题中的例子并不十分清楚它是如何形成的。

如果条目匹配

,则testMatch例程只返回1
sub testMatch
{
  my $elem  = shift;
  my $range = shift;

  return    $elem->{chr}   eq $range->{chr}
         && $elem->{start} >= $range->{start} 
         && $elem->{start} <= $range->{end}
     #    && $elem->{end}   <= $range->{end} # not sure if the segment has to be entirely in the range
  ;

如果您不想重新格式化输入@array,可以在阅读文件之前以编程方式创建重新格式化的内容。     }