1

我想读取一个文件并根据它有多少个链(M,N,O,..)来生成多个数组。

以下是文件的一部分:

SEQRES   1 M  312  ALA ALA ASP PRO LYS LEU LEU LYS ALA ALA ALA GLU ALA
SEQRES   2 M  312  SER TYR ALA PHE ALA LYS GLU VAL ASP TRP ASN ASN GLY
SEQRES   3 M  312  ILE PHE LEU GLN ALA PRO GLY LYS LEU GLN PRO LEU GLU
SEQRES   4 M  312  ALA LEU LYS ALA ILE ASP LYS MET ILE VAL MET GLY ALA
SEQRES   5 M  213  SER PHE ASN ARG ASN

SEQRES   1 N  312  ASP GLU ILE GLY ASP ALA ALA LYS LYS LEU GLY ASP ALA
SEQRES   2 N  312  SER TYR ALA PHE ALA LYS GLU VAL ASP TRP ASN ASN GLY
SEQRES   3 N  312  ILE PHE LEU GLN ALA PRO GLY LYS LEU GLN PRO LEU GLU
SEQRES   4 N  312  ALA LEU LYS ALA ILE ASP LYS MET ILE VAL MET GLY ALA
SEQRES   5 N  312  ALA ALA ASP PRO LYS LEU LEU LYS ALA ALA ALA GLU ALA
SEQRES   6 N  312  VAL THR SER ARG ALA ASP TRP ASP ASN VAL

SEQRES   1 O  312  HIS HIS LYS ALA ILE GLY SER ILE SER GLY PRO ASN GLY
SEQRES   2 O  312  SER TYR ALA PHE ALA LYS GLU VAL ASP TRP ASN ASN GLY
SEQRES   3 O  312  ILE PHE LEU GLN ALA PRO GLY LYS LEU GLN PRO LEU GLU
SEQRES   4 O  312  ALA LEU LYS ALA ILE ASP LYS MET ILE VAL

这是我的代码:

my @seq;
my $string="";
my @seqFile;
my $file=<>;
open(FILE, "$file");
while (my $line=<FILE>){
    if ($line =~ /^SEQRES/) {
        chomp $line;
        push @seq, [split (/\s+/, $line)] ;
    }
}
close(FILE);
for my $i (0..$#seq) {
    my $ob =$seq[$i][2];
    if ($seq[$i][2] eq $ob ){
        for (my $j=4;$j<=$#{$seq[$i]};$j++) {
            my $temp= $seq[$i][$j];
            $string .= $temp;
        }
        $ob = $seq[$i][2];
        last;
    }
    push @seqFile, $ob;
    push @seqFile, $string;
    $string = ''; #string needs to be empty to store new lines
}

使用上面的示例:3 个数组 M(:)ALAALAASP:.., N(:)ASPGLU.., O(:)HISHISLYS...

我设法在一个字符串中创建了所有 SEQRES,但这不是我想要的。

在某个地方我需要放置一个if(){}和来检查M <=> N并且N <=> O是不同的。然后保存字符串并开始一个字符串和数组。但它会不断累积与 $#seq 一样多的相同字符串。或者,如果我移动一个的位置,}那么它不会存储任何东西,或者给我错误消息。我怎样才能做到这一点?

4

2 回答 2

2

你没看到这里有问题吗?

my $ob =$seq[$i][2];
if ($seq[$i][2] ne $ob ){

这类似于:

my $x = "this";
if ($x ne "this) {

条件怎么可能if是真的?

更好的方法是使用数组的散列,以 M、N 或 O 为键(您将 $ob 设置为):

open (my $fh, '<', $file);   # using global globs like FILE is depreciated
my %hash_of_arrays;
while (<$fh>) {
    my @data = split;
    push @{$hash_of_arrays{$data[2]}}, join('', (@data)[4..$#data]);
}

很确定这与您正在尝试做的事情很接近;第二个参数push使用数组 slice

请注意,如果@{$hash{$data[2]}}尚不存在,它将通过autovivification创建:http ://en.wikipedia.org/wiki/Autovivification

于 2012-05-28T11:44:03.403 回答
1

我认为这个程序可以满足您的需求。

我没有观察第三个字段值的变化,而是将其编写为空行或文件末尾标记链的末尾。

use strict;
use warnings;

my $file = 'seq.txt';

open my $fh, '<', $file or die $!;

my @seqFile;
my $string;
my $ob;

while (<$fh>) {
  if (/^SEQRES/) {           
    my @data = split;
    $string .= join '', @data[4..$#data];
    $ob = $data[2];
  }
  if (eof($fh) or not /\S/) {
    push @seqFile, $ob, $string;
    $ob = $string = undef;
  }
}

use Data::Dumper;
print Dumper \@seqFile;

输出

$VAR1 = [
          'M',
          'ALAALAASPPROLYSLEULEULYSALAALAALAGLUALASERTYRALAPHEALALYSGLUVALASPTRPASNASNGLYILEPHELEUGLNALAPROGLYLYSLEUGLNPROLEUGLUALALEULYSALAILEASPLYSMETILEVALMETGLYALASERPHEASNARGASN',
          'N',
          'ASPGLUILEGLYASPALAALALYSLYSLEUGLYASPALASERTYRALAPHEALALYSGLUVALASPTRPASNASNGLYILEPHELEUGLNALAPROGLYLYSLEUGLNPROLEUGLUALALEULYSALAILEASPLYSMETILEVALMETGLYALAALAALAASPPROLYSLEULEULYSALAALAALAGLUALAVALTHRSERARGALAASPTRPASPASNVAL',
          'O',
          'HISHISLYSALAILEGLYSERILESERGLYPROASNGLYSERTYRALAPHEALALYSGLUVALASPTRPASNASNGLYILEPHELEUGLNALAPROGLYLYSLEUGLNPROLEUGLUALALEULYSALAILEASPLYSMETILEVAL'
        ];

编辑

既然我知道数据文件没有空行来描绘链,我原来的解决方案就行不通了。

此替代方法检查记录的第二个字段中的序列号,并在该编号为 1 时启动一个新链。每当新链开始时以及读取循环退出后文件末尾也必须保存累积的链.

该程序的输出与上面显示的相同。

use strict;
use warnings;

my $file = 'seq.txt';

open my $fh, '<', $file or die $!;

my @seqFile;
my $chain;
my $ob;

while (<$fh>) {

  next unless /^SEQRES/;

  my @data = split;
  if ($data[1] == 1) {
    push @seqFile, $ob, $chain if $chain;
    $ob = $chain = undef;
  }
  $chain .= join '', @data[4..$#data];
  $ob = $data[2];
}

push @seqFile, $ob, $chain if $chain;

use Data::Dumper;
print Dumper \@seqFile;
于 2012-05-28T15:50:08.363 回答