perl无法获取所有数组elements.in for(或类似foreach的循环,...)它

时间:2012-11-16 10:48:43

标签: perl

这是我的脚本中的一部分,它在文件中找到包含$ j [1]和$ tt的特定行。 在foreach块中,循环变量只需要获取@pdb文件的前四个元素!!

这是文件:

REMARK   4
REMARK   4
ATOM      1  N   UNK     1      12.964  -9.630   0.000  1.00  0.00
ATOM      2  N   UNK     1      16.585  -9.566   0.000  1.00  0.00
ATOM      3  C   UNK     1      17.270 -10.706   0.000  1.00  0.00
ATOM      4  N   UNK     1      20.927 -10.960   0.000  1.00  0.00
ATOM      5  C   UNK     1      22.257 -10.919   0.000  1.00  0.00
ATOM      6  C   UNK     1      22.886  -9.747   0.000  1.00  0.00
ATOM      7  C   UNK     1      24.215  -9.706   0.000  1.00  0.00
ATOM      8  O   UNK     1      24.992  -8.627   0.000  1.00  0.00
ATOM      9  N   UNK     1      25.815 -10.400   0.000  1.00  0.00
ATOM     10  C   UNK     1      27.131 -10.205   0.000  1.00  0.00
ATOM     11  C   UNK     1      27.620  -8.968   0.000  1.00  0.00
ATOM     12  N   UNK     1      29.548  -8.236   0.000  1.00  0.00
ATOM     13  C   UNK     1      21.133 -12.275   0.000  1.00  0.00
ATOM     14  C   UNK     1      22.373 -12.754   0.000  1.00  0.00
ATOM     15  C   UNK     1      22.579 -14.068   0.000  1.00  0.00
ATOM     16  O   UNK     1      23.819 -14.547   0.000  1.00  0.00
ATOM     17  N   UNK     1      21.284 -14.374   0.000  1.00  0.00
ATOM     18  C   UNK     1      20.304 -15.273   0.000  1.00  0.00
ATOM     19  C   UNK     1      20.593 -16.571   0.000  1.00  0.00
ATOM     20  N   UNK     1      19.612 -17.470   0.000  1.00  0.00
ATOM     21  C   UNK     1      12.355  -8.448   0.000  1.00  0.00
ATOM     22  C   UNK     1      11.027  -8.383   0.000  1.00  0.00
ATOM     23  C   UNK     1      10.418  -7.201   0.000  1.00  0.00
ATOM     24  O   UNK     1       9.090  -7.136   0.000  1.00  0.00
ATOM     25  N   UNK     1      11.131  -6.078   0.000  1.00  0.00
ATOM     26  C   UNK     1      11.870  -4.972   0.000  1.00  0.00
ATOM     27  C   UNK     1      11.282  -3.779   0.000  1.00  0.00
ATOM     28  N   UNK     1      12.020  -2.673   0.000  1.00  0.00
ATOM     29  C   UNK     1      11.794 -10.263   0.000  1.00  0.00
ATOM     30  C   UNK     1      11.757 -11.593   0.000  1.00  0.00
ATOM     31  C   UNK     1      10.587 -12.226   0.000  1.00  0.00
ATOM     32  O   UNK     1      10.550 -13.555   0.000  1.00  0.00
ATOM     33  N   UNK     1       9.563 -11.377   0.000  1.00  0.00
ATOM     34  C   UNK     1       8.238 -11.495   0.000  1.00  0.00
ATOM     35  C   UNK     1       7.678 -12.701   0.000  1.00  0.00
ATOM     36  N   UNK     1       6.353 -12.819   0.000  1.00  0.00
TER      37      UNK     1
CONECT    1    2   21   29
CONECT    2    1    3
CONECT    3    2    4
CONECT    4    3    5   13
CONECT    5    4    6
CONECT    6    5    7
CONECT    7    6    8    9
CONECT    8    7
CONECT    9    7   10
CONECT   10    9   11
CONECT   11   10   12
CONECT   12   11
CONECT   13    4   14
CONECT   14   13   15
CONECT   15   14   16   17
CONECT   16   15
CONECT   17   15   18
CONECT   18   17   19
CONECT   19   18   20
CONECT   20   19
CONECT   21    1   22
CONECT   22   21   23
CONECT   23   22   24   25
CONECT   24   23
CONECT   25   23   26
CONECT   26   25   27
CONECT   27   26   28
CONECT   28   27
CONECT   29    1   30
CONECT   30   29   31
CONECT   31   30   32   33
CONECT   32   31
CONECT   33   31   34
CONECT   34   33   35
CONECT   35   34   36
CONECT   36   35
MASTER        3    0    0    0    0    0    0    0   36    1   36    0
END

和perl脚本:

#!/bin/perl
use strict;
open(pdb,"den.pdb") or die "$!";

my @pdb=<pdb>;
my $n0="N";
my @aa;
my $temp;
my @n1_find;
foreach (@pdb) {
    #$_ as selected line in file
    print $_;
    my @j=split(/\s{1,}/,$_);
    #j : array that contain line elements> eg. j[0] REMARK, ATOM ,...
    if ($j[0] eq "HETATM" or $j[0] eq "ATOM") {
        #print @pdb;
        @aa=grep {/CONECT/ && /\s$j[1]\s/} @pdb ; # pattern that search for CONECT that first N involve in it
        if ($j[2] eq $n0) { # get another N ATOM
            foreach my $ii (splice(@pdb, $temp, $#pdb)) {
                if ($ii=~/$j[0]\s{1,}(\d+)\s{1,}$n0/i) { #search for lines that contain ATOM id "First N" and the second
                    my $tt=$1;
                    if (grep {/CONECT/ && /\s$tt\s/} @aa) { #save both N and exit
                        $n1_find[0]=$j[1];
                        $n1_find[1]=$tt;
                        #$temp=-1;
                    }
                }
            }
        }
    }
    #last if ($temp==-1) ;
    #print $temp+=1;
}

我为退出设置了一个循环条件,但即使我从脚本中删除它也不会获得所有数组变量。 THANX。

1 个答案:

答案 0 :(得分:7)

您的脚本中有几个问题。我不打算详细列出所有这些:错误的变量名,没有注释,奇怪的逻辑,没有use strict;use warnings;,使用open()的不安全的2参数形式和全局文件句柄;没有使用正确的CPAN模块(File::Slurp进行文件读取)。

  • main 一个是你的主循环使用$_默认变量进行循环,而不会被本地化(例如grep)。 / p>

    使用显式循环变量:foreach my $line (@pdb) {

  • 第二个是你在@pdb数组上循环,并在循环内迭代同一个数组(再次使用grep)。它很可能会抛弃循环。

    尝试迭代数组的副本。

    my @pdb2 = @pdb;
    foreach my $line (@pdb2) {
    

一旦你做了这两个小修正,你的脚本至少会遍历外部循环中的所有行。然后你可以开始调试循环中的实际逻辑。