如何使用不同文件中的序列ID从文件中提取FASTA序列?

时间:2018-03-26 08:25:47

标签: perl fasta

我有两个文件:

sequence.fasta - 包含多个FASTA序列的大文件

ids.txt - 由制表符分隔格式的序列ID组成。

我想将这些序列提取到sequence.fasta的另一个文件中,该文件的ID在ids.txt中匹配。

sequence.fasta

的样本
>AUP4056.1
MFKSLIQFFKSKSNTSNIKKENAVQRQERQDIEGWITPYSGQELLNTELRQHHLGLLWQQVSMTREMFEH
LYQKPIERYAEMVQLLPASESHHHSHLGGMLDHGLEVISFAAKLRQNYVLPLNAAPEDQAKQKDAWTAAV
IYLALVHDIGKSIVDIEIQLQDGKRWLAWHGIPTLPYKFRYIKQRDYELHPVLGGFIANQLIAKETFDWL
ATYPEVFSALMYAMAGHYDKANVLAEIVQKADQNSVALALGGDITKLVQKPVISFAKQLI`

>XIM5213.2
FKISSKGPGDGWLTEDGLWLMSKTTADQIRAYLMGQGISVPSDNRKLFDEMQAHRVIESTSEGNAIWYCQ
LSADAGWKPKDKFSLLRIKPEVIWDNIDDRPELFAGTICVVEKENEAEEKISNTVNEVQDTVPINKKENI
ELTSNLQEENTALQSLNPSQNPEVVVENCDNNSVDFLLNMFSDNNEQQVMNIPSADAEAGTTMILKSEPE
NLNTHIEVEANAIPKLPTNDDTHLKSEGQKFVDWLKD

ids.txt

的样本
AUP4056.1 GUP5213.2 ARD5364.5 HAE6893.7
JIK6023.5 YUP7086.9

我需要输出如下

>AUP4056.1
MFKSLIQFFKSKSNTSNIKKENAVQRQERQDIEGWITPYSGQELLNTELRQHHLGLLWQQVSMTREMFEH
LYQKPIERYAEMVQLLPASESHHHSHLGGMLDHGLEVISFAAKLRQNYVLPLNAAPEDQAKQKDAWTAAV
IYLALVHDIGKSIVDIEIQLQDGKRWLAWHGIPTLPYKFRYIKQRDYELHPVLGGFIANQLIAKETFDWL
ATYPEVFSALMYAMAGHYDKANVLAEIVQKADQNSVALALGGDITKLVQKPVISFAKQLI

>GUP5213.2
ELTSNLQEENTALQSLNPSQNPEVVVENCDNNSVDFLLNMFSDNNEQQVMNIPSADAEAGTTMILKSEPE
NLNTHIEVEANAIPKLPTNDDTHLKSEGQKFVDWLKDKLFKKQLTFNDRTAKVHIVNDCLFIVSPSSFEL
YLQEKGESYDEECINNLQYEFQALGLHRKRIIKNDTINFWRCKVIGPKKESFLVGYLVPNTRLFFGDKIL
INNRHLLLEE

我尝试过Perl单线程,但这不起作用。既不给出任何错误也不给出任何输出。

perl -ne 'if(/^>(\S+)/){$c=$i{$1}}$c?print:chomp;$i{$_}=1 if @ARGV' ids.txt sequence.fasta

是否有人可以帮我更正此代码或者是否有其他Perl脚本?

2 个答案:

答案 0 :(得分:3)

这里的问题是单行很难遵循,理解和解开。

所以写出来'长手':

#!/usr/bin/env perl

use strict;
use warnings;

open ( my $id_file, '<', 'ids.txt' ) or die $!;
#use split here, to split any lines on whitespace. 
chomp ( my @ids = map { split } <$id_file> );
close ( $id_file );

my %sequences;

open ( my $input, '<', 'sequence.fasta' ) or die $!;
{
   local $/ = '';    #paragraph mode; Read until blank line

   while ( <$input> ) {
      my ( $id, $sequence ) = m/>\s*(\S+)\n(.*)/ms;
      $sequences{$id} = $sequence;
   }
}

foreach my $id (@ids) {
   if ( $sequences{$id} ) {
      print ">$id\n";
      print "$sequences{$id}\n";
   }
}

如果您想阅读@ARGV中的文件名:

my ( $ids_file, $sequence_file ) = @ARGV; 

我不会尝试将它压缩成一个衬里 - 你可能可以,但是当你回到它时它很难理解。

答案 1 :(得分:-1)

如果您想要一个衬垫 - 您的帖子实际上是建议的 - 这就是您可以做的:

perl -pe '$i=$1if/^>(\S+)/;map$i{$_}++,split;$i{$i}or$_=""' ids.txt seq.fasta