我正在尝试编写一个脚本,该脚本针对先前生成的文件搜索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);
答案 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 $!;