获得以FASTA中特定氨基酸开始的蛋白质序列的标题行

时间:2014-10-03 14:57:30

标签: perl fasta

大家好,所以我一直试图使用PERL只打印来自FASTA文件的以“MAD”或“MAN”(前3个aa)开头的蛋白质序列的标题(整个> gi系列)。但我无法弄清楚哪个部分出了问题。 提前谢谢!

#!usr/bin/perl
use strict;

my $in_file = $ARGV[0];
open( my $FH_IN, "<", $in_file );    ###open to fileholder
my @lines = <$FH_IN>;
chomp @lines;
my $index = 0;

foreach my $line (@lines) {
    $index++;
    if ( substr( $line, 0, 3 ) eq "MAD" or substr( $line, 0, 3 ) eq "MAN" ) {
        print "@lines [$index-1]\n\n";
    } else {
        next;
    }
}

这是FASTA文件的一小部分,第一个seq的标题是我正在寻找的

>gi|16128078|ref|NP_414627.1| UDP-N-acetylmuramoyl-L-alanyl-D-glutamate:meso-diaminopimelate ligase [Escherichia coli str. K-12 substr. MG1655] MADRNLRDLLAPWVPDAPSRALREMTLDSRVAAAGDLFVAVVGHQADGRRYIPQAIAQGVAAIIAEAKDE ATDGEIREMHGVPVIYLSQLNERLSALAGRFYHEPSDNLRLVGVTGTNGKTTTTQLLAQWSQLLGEISAV MGTVGNGLLGKVIPTENTTGSAVDVQHELAGLVDQGATFCAMEVSSHGLVQHRVAALKFAASVFTNLSRD HLDYHGDMEHYEAAKWLLYSEHHCGQAIINADDEVGRRWLAKLPDAVAVSMEDHINPNCHGRWLKATEVN

2 个答案:

答案 0 :(得分:2)

您的打印声明有问题。应该是:

print "$lines[$index-1]\n\n";

然而,通常最好只逐行处理文件,除非有特定原因需要扼杀整个文件:

#!usr/bin/perl
use strict;
use warnings;
use autodie;

my $file = shift;

#open my $fh, "<", $in_file;
my $fh = \*DATA;

while (<$fh>) {
    print if /^>/ && <$fh> =~ /^MA[DN]/;
}

__DATA__
>gi|16128078|ref|NP_414627.1| UDP-N-acetylmuramoyl-L-alanyl-D-glutamate:meso-diaminopimelate ligase [Escherichia coli str. K-12 substr. MG1655] 
MADRNLRDLLAPWVPDAPSRALREMTLDSRVAAAGDLFVAVVGHQADGRRYIPQAIAQGVAAIIAEAKDE
ATDGEIREMHGVPVIYLSQLNERLSALAGRFYHEPSDNLRLVGVTGTNGKTTTTQLLAQWSQLLGEISAV
MGTVGNGLLGKVIPTENTTGSAVDVQHELAGLVDQGATFCAMEVSSHGLVQHRVAALKFAASVFTNLSRD
HLDYHGDMEHYEAAKWLLYSEHHCGQAIINADDEVGRRWLAKLPDAVAVSMEDHINPNCHGRWLKATEVN
–

输出:

>gi|16128078|ref|NP_414627.1| UDP-N-acetylmuramoyl-L-alanyl-D-glutamate:meso-diaminopimelate ligase [Escherichia coli str. K-12 substr. MG1655] 

答案 1 :(得分:0)

由于您想知道如何改进代码,因此以下是您的程序的评论版本,并提供了有关如何更改代码的一些建议。

#!/usr/bin/perl
use strict;

您还应该添加use warnings pragma,它会启用警告(正如您所料)。

my $in_file = $ARGV[0];

最好检查$ARGV[0]是否已定义,如果不是,则给出相应的错误消息,例如

my $in_file = $ARGV[0] or die "Please supply the name of the FASTA file to process";

如果未定义$ARGV[0],Perl将执行die语句。

open( my $FH_IN, "<", $in_file );  # open to fileholder

您应该检查脚本是否能够打开输入文件;通过添加die语句,您可以使用与前一个语句类似的结构:

open( my $FH_IN, "<", $in_file ) or die "Could not open $in_file: $!";

特殊变量$!包含无法打开文件的错误消息(例如,它不存在,没有读取权限等)。

my @lines = <$FH_IN>;
chomp @lines;
my $index = 0;

foreach my $line (@lines) {
    $index++;
    if ( substr( $line, 0, 3 ) eq "MAD" or substr( $line, 0, 3 ) eq "MAN" ) {
         print "@lines [$index-1]\n\n";

这是脚本中的问题点。首先,访问数组中项目的正确方法是使用$lines[$index-1]。其次,数组中的第一项是索引0,因此文件的第1行将位于@lines中的位置0,位置3中的第4行,等等。因为您已经增加了索引,您在标题行后打印行。通过在循环结束时递增$index可以很容易地解决问题。

    }
    else {
       next;
    }

在这里使用next并不是必需的,因为else语句后面没有代码,因此告诉Perl跳过其余的循环没有任何好处

固定代码如下所示:

#!/usr/bin/perl
use warnings;
use strict;

my $in_file = $ARGV[0] or die "Please supply the name of the FASTA file to be processed";
open( my $FH_IN, "<", $in_file ) or die "Could not open $in_file: $!";
my @lines = <$FH_IN>;
chomp @lines;

my $index = 0;
foreach my $line (@lines) {
    if ( substr( $line, 0, 3 ) eq "MAD" or substr( $line, 0, 3 ) eq "MAN" ) {
        print "$lines[$index-1]\n\n";
    }
    $index++;
}

我希望这有用而且清晰!