Perl foreach中的if语句

Perl foreach中的if语句,perl,Perl,我正在尝试编写一个子函数,允许用户键入某些内容,该函数将在文件中搜索包含这些内容的行。我遇到的主要问题是foreach语句中的if语句。我的主要目标是查看用户键入的三个变量是否与文件中的某些列匹配。如果他们这样做,那么某些列将被带到他们的特定变量 我的数据如下所示: ATOM 4851 O PRO A 715 89.164 76.083 75.292 1.00 99.41 O ATOM 4852 CB PRO A 715 88.

我正在尝试编写一个子函数,允许用户键入某些内容,该函数将在文件中搜索包含这些内容的行。我遇到的主要问题是foreach语句中的if语句。我的主要目标是查看用户键入的三个变量是否与文件中的某些列匹配。如果他们这样做,那么某些列将被带到他们的特定变量

我的数据如下所示:

ATOM   4851  O   PRO A 715      89.164  76.083  75.292  1.00 99.41           O  
ATOM   4852  CB  PRO A 715      88.324  78.267  73.865  1.00 95.88           C  
ATOM   4853  CG  PRO A 715      88.836  78.838  72.540  1.00 95.93           C  
例如,如果用户在PRO a715中键入,那么foreach将遍历所有行,if语句将看起来满足这些条件,然后将取出坐标

x坐标:89.164、88.324、88.836

y坐标:76.083、78.267、78.838

z坐标:75.292,73.865,72.540

我的错误是:

Can't modify logical and (&&) in scalar assignment at ./pdbtool.pl line 75, near ") ) "
我的计划是:

open (FILE, $ARGV[0])
    or die "Could not open file\n";

my @newlines;
while ( my $line = <FILE> ) {
    if ($line =~ m/^ATOM.*/) {
    push @newlines, $line;
    }
}

sub reslength {
#User will type in the information
print "Type Residue Name:\n";
my $residue = <STDIN>;
chomp($residue);
print "Type Chain ID:\n";
my $chainid = <STDIN>;
chomp ($chainid);
print "Type Residue Sequence Number\n";
my $resseq = <STDIN>;
chomp ($resseq);

#The function will go through each line and match the info along with pushing it to a new vairable
my @arrayx;
my @arrayy;
my @arrayz;

    foreach my $record3(@newlines) {
      if ( $residue = substr($record3, 17, 3) && $chainid = substr($record3, 21, 1) && $resseq = substr($record3, 22, 4) ) {
            @arrayx = substr($record3, 30, 8);
            @arrayy = substr($record3, 38, 8);
            @arrayz = substr($record3, 46, 8);
            }
    }
#Now I will find the distance between these x,y,z coordinates
my $distance = sqrt[(@arrayx(1)-@arrayx(0))^2 + (@arrayy(1)-@arrayy(0))^2 + (@arrayz(1)-@arrayz(0))^2)]
print "$resname with sequence number $resseq in $chainid has length $distance angstroms.\n"
打开(文件$ARGV[0])
或“无法打开文件”\n;
我的@newlines;
while(我的$line=){
如果($line=~m/^ATOM.*/){
按@newlines,$line;
}
}
子长度{
#用户将输入信息
打印“键入剩余名称:\n”;
我的$剩余=;
咀嚼(残渣);
打印“类型链ID:\n”;
我的$chainid=;
chomp($chainid);
打印“键入剩余序列号\n”;
我的$Q=;
chomp($reseq);
#该函数将遍历每一行并匹配信息,同时将其推送到一个新的VARABLE
我的@arrayx;
我的@arrayy;
我的@arrayz;
foreach my$record3(@newlines){
if($residence=substr($record3,17,3)和&$chainid=substr($record3,21,1)和&$reseq=substr($record3,22,4)){
@arrayx=substr($record3,30,8);
@arrayy=substr($record3,38,8);
@arrayz=substr($record3,46,8);
}
}
#现在我将求出这些x,y,z坐标之间的距离
我的$distance=sqrt[(@arrayx(1)-@arrayx(0))^2+(@arrayy(1)-@arrayy(0))^2+(@arrayz(1)-@arrayz(0))^2]
打印“$chainid中序列号为$RESEQ的$resname的长度为$distance埃。\n”

}您不能在这样的if语句中修改变量。 我想你可能想做一个比较检查

if ( $residue == substr($record3, 17, 3) && $chainid == substr($record3, 21, 1) && $resseq == substr($record3, 22, 4) ) 
然而,这带来了另一个$distance错误 要访问数组中的变量,应使用$array[$num]

my $distance = sqrt[($arrayx[1]-$arrayx[0])^2 + ($arrayy[1]-$arrayy[0])^2 + ($arrayz[1]-$arrayz[0])^2];

perl疑难解答的第一步是打开
use strict
使用警告因为这将告诉您代码的问题

您使用
sqrt
的代码片段几乎肯定是个问题,因为您使用了错误的括号,并且省略了分号

然而,除此之外:

  • 您定义了一个子
    reslength
    并将大部分代码放入其中,然后再也不会实际调用它
  • 在比较中使用
    =
    ,而不是
    =
    <代码>=
是一个赋值,其中
=
是一个比较
  • substr
    匹配以空格分隔的内容是脆弱的。尝试正则表达式或
    split
  • 调用
    sqrt
    时应使用
  • 查看数组标记时,应使用
    [
  • <>你正在打开一个在<代码> > $ARGV(0)< /代码>中指定的文件——你应该考虑只使用<代码> <代码>,它做同样的事情(但也会做多个文件)。
  • 您正在将一个文件读入一个数组,然后迭代该数组。为什么不直接迭代该文件呢
  • 您应该使用带词法文件句柄的3参数open
  • 作为10的开始-这将把你的坐标读入一个数组

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    use Data::Dumper;
    
    #replace this bit with your 'user input' once you're done testing. 
    
    my $residue = 'PRO';
    my $chainid = 'A';
    my $resseq = '715'; 
    
    my @coords; 
    
    open ( my $input, '<', $ARGV[0] ) or die $!; 
    while ( <$input> ) {
    
       next unless m/^ATOM/; 
       my @fields = split;
       my ( $res, $chain, $seq, $x_coord, $y_coord, $z_coord ) = @fields[3..8];
    
       next unless $residue eq $res;
       next unless $chainid eq $chain;
       next unless $resseq eq $seq; 
    
       #insert into array of coordinates. Could flip order, and 
       push ( @{$coords[0]}, $x_coord );
       push ( @{$coords[1]}, $y_coord );
       push ( @{$coords[2]}, $z_coord );
    
    }
    close ( $input );
    
    #print for debugging - what have we read in.     
    print Dumper \@coords;
    
    
    my $distance = sqrt ( ( $coords[0][1] - $coords[0][0]  ) ^ 2
                        + ( $coords[1][1] - $coords[1][0] ) ^ 2
                        + ( $coords[2][1] - $coords[2][0] ) ^ 2 );
    
    print "$residue with sequence number $resseq in $chainid has length $distance angstroms.\n"
    

    “您不能在这样的if语句中修改变量”--您可以在
    if
    中赋值,甚至可以声明,
    if((my$v=func(…)!=num){..$v..}
    ,其中围绕赋值的排列是必要的。但你是对的,OP似乎需要
    =
    ,而不是
    =
    。我认为这段代码需要重写。你能澄清一下你例子中的哪个坐标需要计算距离吗?我不明白你是如何使用一个3坐标的例子的,然后只是尝试使用其中两个在sqrt中。
    PRO with sequence number 715 in A has length 2.44948974278318 angstroms.