这是我用来模式匹配的脚本。我没有得到我需要的确切输出请帮帮我..
#!/usr/bin/perl5.14.4
open(LIST, "/home/guest/Desktop/hpresult.txt")
or die ("Couldn't open the Result");
@list = <LIST>;
close LIST;
open(OUTPUT, ">/home/guest/Desktop/sortresult3")
or die ("couldn't write the file");
$line = (@list);
foreach $line(@list) {
if($line =~ m/>/g) {
$pdbid = substr($line, 0);
}
if($line =~ m/Found/g) {
$id = $line;
print OUTPUT $pdbid . $id;
}
}
INPUT
hpresult.txt
>3ior_B
Found PPPPPPPPPPP at 397 to 407 of length 11
Found QQQQQQQQQ at 388 to 396 of length 9
>3ior_C
Found QQQQQQQQQQQQQ at 388 to 400 of length 13
>3ios_A
>3iot_A
输出(我得到的)
>3ior_B
Found PPPPPPPPPPP at 397 to 407 of length 11
>3ior_B
Found QQQQQQQQQ at 388 to 396 of length 9
>3ior_C
Found QQQQQQQQQQQQQ at 388 to 400 of length 13
所需的输出
>3ior_B
Found PPPPPPPPPPP at 397 to 407 of length 11
Found QQQQQQQQQ at 388 to 396 of length 9
>3ior_C
Found QQQQQQQQQQQQQ at 388 to 400 of length 13
请帮我解决这个问题..
答案 0 :(得分:3)
关于代码的一些注意事项。修复这些问题后,您应该有一个完全不同的程序来处理,或者应该提出一个新问题:
始终,始终使用
use strict;
use warnings;
特别是Perl的新手。 strict
将帮助您避免混淆范围和变量名称(强制您使用my
显式声明变量)等等。 warnings
会警告你,你正在做的事情可能是无心的。学习使用这两个pragma所需的时间,您将在以后缩短调试时间,并对您的程序有更多控制权。
open(LIST, "/home/guest/Desktop/hpresult.txt")
or die ("Couldn't open the Result");
@list = <LIST>;
close LIST;
open(OUTPUT, ">/home/guest/Desktop/sortresult3")
or die ("couldn't write the file");
在这里打开两个文件句柄并将文件粘贴到数组中。在这样的小程序中,在我看来,最好不对输入和输出文件进行硬编码,而是使用菱形运算符,并依赖shell重定向将输出保存到文件中。将文件粘贴到数组中效率很低。
以下是它的基本要点,取代所有这些文件处理:
my $junk = <>; # take first line away
while (<>) { # reads the argument file names line-by-line
# process lines here
}
如果你想打开文件,你应该使用三个参数open(使用显式MODE)和一个词法文件句柄:
open my $fh, "<", $file or die "Cannot open file for reading: $!";
这一行:
$line = (@list);
是完全冗余的,考虑以下行,您可以在其中启动for循环。它会将@list
的最后一个元素分配给$line
,在下一行中,它将使用本地化版本“覆盖”该值。但是,在循环之后,$line
将返回此值,毫无疑问会让您感到困惑。请参阅他们询问有关本地化变量的this question。
我不确定你在这里要做什么。我假设您可能尝试获取文件中的第一行并将其删除。如果是这种情况,您只需执行
即可shift @list;
但正如您将看到的那样,因为将文件读入数组并不是最佳解决方案,所以我们不会使用它。
if($line =~ m/>/g) {
$pdbid = substr($line, 0);
}
if($line =~ m/Found/g) {
$id = $line;
print OUTPUT $pdbid . $id;
}
正如ikegami所说,使用/g
修饰符和if
语句是没有意义的。此外,substr($line, 0)
将获取字符串$line
的完整副本。不确定你在那里做什么。但在这种情况下编写$pdbid = $line
更简单(并且更少混淆)。
如果您需要所需的输出,则需要区分不同的标题,可能使用变量来记住您打印的标题
if ($line =~ /Found/) {
print $pdbid if $printed_pdbid ne $pdbid;
print $line;
$printed_pdbid = $pdbid;
}
所以,基本上你需要的是
use strict;
use warnings;
my $junk = <>;
my $old = ""; # to avoid undef warning
my ($current, $pdbid);
while (<>) {
if (/^>/) { # if line begins with >
$pdbid = $_; # store header
} elsif (/Found/) { # automatically skip to next line
print $pdbid if $old ne $pdbid;
$old = $pdbid; # store old header
print $_; # print current line
}
}
将提供以下输出:
>3ior_B
Found PPPPPPPPPPP at 397 to 407 of length 11
Found QQQQQQQQQ at 388 to 396 of length 9
>3ior_C
Found QQQQQQQQQQQQQ at 388 to 400 of length 13
您还可以使用段落模式,其中包括更改输入记录分隔符$/
以使Perl考虑以两个换行符结尾的行\n\n
:
my $junk = <>; # before changing $/ reads single line
$/ = "\n\n"; # input record separator
$\ = "\n\n"; # output record separator (for print())
while (<>) { # read paragraph
chomp;
my ($hdr, @lines) = split /(?=\n)/; # split paragraph
print ($hdr, @lines) if @lines; # if @lines is empty, skip
}
这有点不真实,因为真正的段落模式涉及将输入记录分隔符设置为空字符串$/ = ""
,但在这种情况下,由于我们正在取出新行并将它们放回去,所以最好是保持一致。
另请注意,由于我们使用前瞻断言(?=...)
拆分段落,因此我们实际上并未删除换行符,而是将其保存以用于打印。但是,我们正在使用chomp
删除段落换行符。
此处列出的我的程序的用法是
perl script.pl input > output
如果您只想查看输出,请跳过带有重定向的最后一部分
perl script.pl input
答案 1 :(得分:2)
您的文件有fasta外观,而且您还可以使用序列位置/长度。
与fasta文件一样,您的文件包含以“&gt;”分隔的记录,因此我们可以通过将Perl的记录分隔符$/
设置为“&gt;”来读取这些“块”中的文件,然后查找“发现“在那些块中。如果找到“找到”,则打印块:
use strict;
use warnings;
local $/ = '>';
while (<>) {
chomp;
print ">$_" if /Found/;
}
用法:perl script.pl inFile >outFile
数据集输出:
>3ior_B
Found PPPPPPPPPPP at 397 to 407 of length 11
Found QQQQQQQQQ at 388 to 396 of length 9
>3ior_C
Found QQQQQQQQQQQQQ at 388 to 400 of length 13
希望这有帮助!
答案 2 :(得分:0)
尝试使用:
# ALWAYS
use strict;
use warnings;
my $filein = "/home/guest/Desktop/hpresult.txt";
my $fileout = "/home/guest/Desktop/sortresult3";
# use 3-arg open
open my $LIST, '<', $filein or die "Unable to open '$filein': $!";
open my $OUT, '>', $fileout or die "Unable to open '$fileout': $!";
my $id;
while(my $line = <$LIST>) {
chomp $line;
if ($line =~ />/) {
$id = $line;
} elsif ($line =~ /Found/) {
print $OUT $id,"\n" if $id;
# id is printed only once
$id = '';
print $OUT $line,"\n";
}
}