-4

これは、ファイル内の $j[1] と $tt の両方を含む特定の行を見つける私のスクリプトの一部です。foreach ブロックでは、ループ変数は @pdb ファイルの最初の 4 つの要素を取得するだけです!!

ここにファイルがあります:

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;
}

exit のループ条件を配置しましたが、スクリプトから削除しても、すべての配列変数が取得されません。Xさん。

4

1 に答える 1

7

スクリプトにいくつかの問題があります。それらすべてを詳細にリストすることは気にしません: 悪い変数名、コメントなし、奇妙なロジック、 no use strict;use warnings;、安全でない 2 引数形式のopen()グローバル ファイル ハンドルの使用。適切な CPAN モジュールを使用していない (File::Slurpファイル読み取り用)。

  • ものは、メイン ループ$_がローカライズされずに内部で上書きされるループ用のデフォルト変数を使用することです (例: によってgrep)。

    明示的なループ変数を使用します。foreach my $line (@pdb) {

  • 2 つ目は、配列をループし@pdb、ループ内で同じ配列を反復処理することです (再び を使用しますgrep)。ループから外れてしまう可能性が非常に高いです。

    配列のコピーを反復処理してみてください。

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

これら 2 つのマイナーな修正を行うと、少なくとも、スクリプトは外側のループのすべての行を反復処理します。その後、ループ内の実際のロジックのデバッグを開始できます。

于 2012-11-16T11:23:27.893 に答える