perl - 关闭if语句时语法不正确

时间:2013-10-11 17:25:11

标签: perl if-statement syntax-error

我正在尝试编写一个脚本,该脚本针对先前生成的文件搜索BLAST输出,该文件提供每个GI编号的基因组位置。但是,我得到三个与关闭IF语句相关的语法错误。作为Perl的新手,我对如何解决这个问题感到很茫然。谁能帮我?我复制了代码并标记了违规的结束括号。我确实做了一个快速检查,以确保所有分隔符均衡。

#!/usr/bin/perl -w

#decided to have input file entered in command line
#call program followed by genome name. 
#the program assumes that a file with the extensions ptt and faa exist in the same dirctory. 


#####INPUT Name of multiple seq file containing ORF of genome, open file and assign IN filehandle ############# 

unless(@ARGV==2) {die "usage: perl nucnums.pl BLAST_output_filename query.ref subject.ref\n\nSubject is the database you made with FormatDB or MakeBlastDB.\n\nQuery is the other file";}

$blastname=$ARGV[0];  
$queryname=$ARGV[1];
$subjectname=$ARGV[2];
@nameparts=split(/\./, $blastname);
$ofilename="$blastname[0]"."pos";
open(INBLAST, "< $blastname") or die "cannot open $blastname:$!";

open(OUT, "> $ofilename") or die "cannot open $ofilename:$!";
$line=<INBLAST>;
print OUT $line;
while (defined ($line=<INBLAST>)){ # read through rest of table line by line
    if ($line=/^g/){
        @parts=split/\t/,$line;
        @girefq=split/\|/,$parts[0];
        $ginumq = ($girefq[1]);
        $postartq = $parts[6];
        @girefs=split/|/,$parts[1];
        $ginums = ($girefs[1]);
        $postarts = $parts[8];
        open(INQUER, "< $queryname") or die "cannot open $queryname:$!"; 
        open(INSUBJ, "< $subjectname") or die "cannot open $subjectname:$!";
        SCOOP: while (defined ($locq=<INQUER>)){
            @locsq=split/\t/,$locq
            if $locsq[0] = $ginumq{
                $posq = $locsq[1] + $postartq - 1;
                } # <- Syntax error

            }
        close(INQUER);
        SLOOP: while (defined ($locs=<INSUBJ>)){
            @locsq=split/\t/,$locs
            if $locss[0] = $ginums {
                $poss = $locss[1] + $postarts - 1;
                } # <- Syntax error

            }
        close(INSUBJ);
        print "$ginumq at position $posq matches with $ginums at position $poss \n" or die "Failed to find a match, try changing the order of the REF files";
        print OUT "$ginumq\t$posq\t$ginums\t$poss\t$parts[2]\t$parts[3]\t$parts[4]\t$parts[5]\t$parts[6]\t$parts[7]\t$parts[8]\t$parts[9]\t$parts[10]\t$parts[11]\t$parts[12]\n";
        } # <- Syntax error
    }

close(OUT);
close(INBLAST);

3 个答案:

答案 0 :(得分:2)

您需要更改:

@locsq=split/\t/,$locs
if $locss[0] = $ginums {

类似于:

@locsq=split/\t/,$locs;
if ($locss[0] == $ginums) {

同样适用于$locsq[0]。如果您要比较字符串而不是数字,请使用eq代替==

更新:感谢Zaid指出丢失的分号。

答案 1 :(得分:2)

@locsq=split/\t/,$locs
if $locss[0] = $ginums {
     $poss = $locss[1] + $postarts - 1;
} # <- Syntax error

你在这里得到一个误导性的错误信息,因为它的第一部分在语法上是有效的,虽然不是你想要的。第一行缺少的分号表示上面的第一部分被解析为后缀if(因为后缀if中的条件不需要括号):

@locsq=split/\t/,$locs if $locss[0] = $ginums

不仅如此,以$ginums{开头的部分被解析为对哈希元素的引用。 (没有%ginums哈希,但在任何语法错误之后会报告错误):

@locsq=split/\t/,$locs if $locss[0] = $ginums{$poss = $locss[1] + $postarts - 1;} 

其中$poss = $locss[1] + $postarts - 1;被视为哈希键。

由于}之前的分号,您只收到语法错误消息。如果你省略了那个分号,你可能会抱怨%ginums不存在(假设你有use strict; use warnings;;如果没有,你可能根本就没有得到警告。

这是拼写错误可以将一段代码转换为有效代码(或者,在这种情况下几乎有效)的情况之一,但这并不意味着你想要的东西。

在第一行的末尾添加分号,并为if条件加上括号。

答案 2 :(得分:1)

在对它进行任何测试之前,您似乎已经编写了整个程序。这不是要走的路。您应该编写小部分并测试它们是否单独工作,然后再添加它们或将它们组装到完整的程序中。

use warnings比将-w放在#!行更可取。

如果您在程序顶部添加use strict并使用my声明所有变量,则此程序中还会出现一些错误。例如,你写

$ofilename   = "$blastname[0]" . "pos";

但没有@blastname数组。 $ofilename最终只会包含pos,但use strict不允许您在此条件下运行该程序。

你也写(我认为应该是什么)

  my @locsq = split /\t/, $locs;
  if ($locss[0] = $ginums) {
    $poss = $locss[1] + $postarts - 1;
  }

并且,同样没有@locss数组,因此除非if为空字符串,否则永远不会执行此$ginums

我建议你至少看看你的程序的重写,它使用了普遍接受的良好实践,我希望你会同意更具可读性。

您的最终print语句存在问题,因为控制台的print始终返回true,因此die永远不会被执行,但我不了解什么你正在修理它。

use strict;
use warnings;

unless (@ARGV == 2) {
  die <<END;
usage: perl nucnums.pl BLAST_output_filename query.ref subject.ref

Subject is the database you made with FormatDB or MakeBlastDB.

Query is the other file
END
}

my ($blastname, $queryname, $subjectname) = @ARGV;
my @nameparts = split /\./, $blastname;
my $ofilename = "${blastname}pos";

open my $inblast, '<', $blastname or die "cannot open $blastname: $!";
open my $out,     '>', $ofilename or die "cannot open $ofilename: $!";
print $out scalar <$inblast>;

while (my $line = <$inblast>) {

  next unless $line =~ /^g/;

  my @parts    = split /\t/, $line;
  my @girefq   = split /\|/, $parts[0];
  my $ginumq   = $girefq[1];
  my $postartq = $parts[6];
  my @girefs   = split /|/, $parts[1];
  my $ginums   = $girefs[1];
  my $postarts = $parts[8];

  my ($posq, $poss);

  open my $inquer, '<', $queryname or die "cannot open $queryname: $!";
  while (my $locq = <$inquer>) {
    my @locsq = split /\t/, $locq;
    if ($locsq[0] = $ginumq) {
      $posq = $locsq[1] + $postartq - 1;
    }
  }
  close($inquer);

  open my $insubj, '<', $subjectname or die "cannot open $subjectname: $!";
  while (my $locs = <$insubj>) {
    my @locss = split /\t/, $locs;
    if ($locss[0] = $ginums) {
      $poss = $locss[1] + $postarts - 1;
    }
  }
  close($insubj);

  print "$ginumq at position $posq matches with $ginums at position $poss \n"
      or die "Failed to find a match, try changing the order of the REF files";

  print $out join("\t", $ginumq, $posq, $ginums, $poss, @parts[2..12]), "\n";


}

close $inblast;
close $out or die $!;