使用Perl从FASTA文件添加序列

时间:2015-11-09 17:28:35

标签: perl sequence fasta

我还在学习Perl,我有一个能够获取FASTA文件序列标题并在方括号内仅打印物种名称的程序。我想添加这个代码,让它也打印出与物种相关的整个序列。

这是我的代码:

#!/usr/bin/perl
use warnings;

my $file = 'seqs.fasta';
my $tmp = 'newseqs.fasta';
open(OUT, '>', $tmp) or die "Can't open $tmp: $!";
open(IN, '<', $file) or die "Can't open $file: $!";

while(<IN>) {
    chomp;
    if ( $_ =~ /\[([^]]+)\]/ ) {
        print OUT "$1\n";
    }
}

close(IN);
close(OUT);

以下是我原始FASTA文件的示例:

>gi|334187971|ref|NP_001190408.1| Cam-binding protein 60-like G [Arabidopsis thaliana] >gi|332006244|gb|AED93627.1| Cam-binding protein 60-like G [Arabidopsis thaliana]
MKIRNSPSFHGGSGYSVFRARNLTFKKVVKKVMRDQSNNQFMIQMENMIRRIVREEIQRSLQPFLSSSCVSMERSRSETP
SSRSRLKLCFINSPPSSIFTGSKIEAEDGSPLVIELVDATTNTLVSTGPFSSSRVELVPLNADFTEESWTVEGFNRNILT
QREGKRPLLTGDLTVMLKNGVGVITGDIAFSDNSSWTRSRKFRLGAKLTGDGAVEARSEAFGCRDQRGESYKKHHPPCPS
DEVWRLEKIAKDGVSATRLAERKILTVKDFRRLYTIIGAGVSKKTWNTIVSHAMDCVLDETECYIYNANTPGVTLLFNSV
YELIRVSFNGNDIQNLDQPILDQLKAEAYQNLNRITAVNDRTFVGHPQRSLQCPQDPGFVVTCSGSQHIDFQGSLDPSSS
SMALCHKASSSTVHPDVLMSFDNSSTARFHIDKKFLPTFGNSFKVSELDQVHGKSQTVVTKGCIENNEEDENAFSYHHHD
DMTSSWSPGTHQAVETMFLTVSETEEAGMFDVHFANVNLGSPRARWCKVKAAFKVRAAFKEVRRHTTARNPREGL

目前,产量仅拉动物种名称​​拟南芥

但是,我希望它能够在fasta文件中正确打印:

>Arabidopsis thaliana
MKIRNSPSFHGGSGYSVFRARNLTFKKVVKKVMRDQSNNQFMIQMENMIRRIVREEIQRSLQPFLSSSCVSMERSRSETP
SSRSRLKLCFINSPPSSIFTGSKIEAEDGSPLVIELVDATTNTLVSTGPFSSSRVELVPLNADFTEESWTVEGFNRNILT
QREGKRPLLTGDLTVMLKNGVGVITGDIAFSDNSSWTRSRKFRLGAKLTGDGAVEARSEAFGCRDQRGESYKKHHPPCPS
DEVWRLEKIAKDGVSATRLAERKILTVKDFRRLYTIIGAGVSKKTWNTIVSHAMDCVLDETECYIYNANTPGVTLLFNSV
YELIRVSFNGNDIQNLDQPILDQLKAEAYQNLNRITAVNDRTFVGHPQRSLQCPQDPGFVVTCSGSQHIDFQGSLDPSSS
SMALCHKASSSTVHPDVLMSFDNSSTARFHIDKKFLPTFGNSFKVSELDQVHGKSQTVVTKGCIENNEEDENAFSYHHHD
DMTSSWSPGTHQAVETMFLTVSETEEAGMFDVHFANVNLGSPRARWCKVKAAFKVRAAFKEVRRHTTARNPREGL

您能否建议修改代码以实现此目的?

2 个答案:

答案 0 :(得分:2)

那是因为这样做:

if ( $_ =~ /\[([^]]+)\]/ ) {
        print OUT "$1\n";
}

查找并捕获[]中的任何文字。但是如果那个模式没有匹配,你就不会对该行做任何其他事情 - 比如打印它。

添加:

else {
    print OUT $_;
}

意味着如果一行包含[],它将默认打印。

我还建议:

  • 开启use strict;
  • 词法文件句柄是一种很好的做法:open ( my $input, '<', $file ) or die $!;
  • 默认情况下,模式匹配隐式应用于$_。所以你可以把'if'写成if ( /\[([^]]+)\]/ )

答案 1 :(得分:0)

关于您的计划的一些一般性观点

  • 必须始终 use strict以及您编写的每个Perl程序顶部的use warnings 'all'。它将揭示许多你可能容易忽视的简单错误

  • 您已选择open的三参数形式,但您也应该使用词法文件句柄。所以这一行

    open(OUT, '>', $tmp) or die "Can't open $tmp: $!";

should be written as
    open my $out_fh, '>', $tmp or die "Can't open $tmp: $!";
  • 最好在命令行上提供输入和输出文件名,这样您就不必编辑程序以针对不同的文件运行它

我会像这样解决你的问题。它检查每行是否是包含方括号括起来的字符串的标题。第一个测试是该行以一个近角括号>开始,第二个测试与您在自己的程序中编写的相同,它捕获括号中的字符串 - 物种名称

如果传递了这些检查,那么物种名称将打印出一个关闭角括号和换行符,否则该行将按原样打印

这个程序应该像这样运行

$ fasta_species.pl seqs.fasta > newseqs.fasta

美元只是Linux提示符,它假定您已将程序放在文件名fasta_species.pl中。您可以省略> newseqs.fasta直接在屏幕上显示输出,这样您就可以在不创建输出文件和编辑输出文件的情况下查看正在生成的内容

use strict;
use warnings 'all';

while ( <> ) {
    if ( /^>/ and / \[ ( [^\[\]]+ ) \] /x ) {
        print ">$1\n";
    }
    else {
        print;
    }
}

输出

>Arabidopsis thaliana
MKIRNSPSFHGGSGYSVFRARNLTFKKVVKKVMRDQSNNQFMIQMENMIRRIVREEIQRSLQPFLSSSCVSMERSRSETP
SSRSRLKLCFINSPPSSIFTGSKIEAEDGSPLVIELVDATTNTLVSTGPFSSSRVELVPLNADFTEESWTVEGFNRNILT
QREGKRPLLTGDLTVMLKNGVGVITGDIAFSDNSSWTRSRKFRLGAKLTGDGAVEARSEAFGCRDQRGESYKKHHPPCPS
DEVWRLEKIAKDGVSATRLAERKILTVKDFRRLYTIIGAGVSKKTWNTIVSHAMDCVLDETECYIYNANTPGVTLLFNSV
YELIRVSFNGNDIQNLDQPILDQLKAEAYQNLNRITAVNDRTFVGHPQRSLQCPQDPGFVVTCSGSQHIDFQGSLDPSSS
SMALCHKASSSTVHPDVLMSFDNSSTARFHIDKKFLPTFGNSFKVSELDQVHGKSQTVVTKGCIENNEEDENAFSYHHHD
DMTSSWSPGTHQAVETMFLTVSETEEAGMFDVHFANVNLGSPRARWCKVKAAFKVRAAFKEVRRHTTARNPREGL