0

我正在尝试编写一个脚本,根据先前生成的文件搜索 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);
4

3 回答 3

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

where$poss = $locss[1] + $postarts - 1;作为哈希键。

由于}. %ginums如果您省略了该分号,您可能会收到关于不存在的抱怨(假设您有use strict; use warnings;; 否则您可能根本不会收到警告)。

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

在第一行的末尾添加一个分号,并将if条件括起来。

于 2013-10-11T17:43:59.467 回答
2

你需要改变:

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

类似于:

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

也一样$locsq[0]。如果您要比较字符串而不是数字,请使用eq而不是==.

更新:感谢 Zaid 指出缺少的分号。

于 2013-10-11T17:27:49.153 回答
1

看起来您在对其进行任何测试之前已经编写了整个程序。那不是要走的路。您应该编写小部分并测试它们是否独立工作,然后再添加它们或将它们组装成完整的程序。

use warnings-w比上线更可取#!

如果您use strict在程序顶部添加并使用my. 例如,你写

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

但没有@blastname数组。$ofilename最终将始终包含 just 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 $!;
于 2013-10-11T18:46:16.837 回答