我不知道这是否只是Stawberry Perl的一个怪癖,但我似乎无法让它运行。我只需要取一个fasta并反转其中的每个序列。
- 问题 -
我有一个multifasta文件:
>seq1
ABCDEFG
>seq2
HIJKLMN
,预期输出为:
>REVseq1
GFEDCBA
>REVseq2
NMLKJIH
脚本在这里:
$NUM_COL = 80; ## set the column width of output file
$infile = shift; ## grab input sequence file name from command line
$outfile = "test1.txt"; ## name output file, prepend with “REV”
open (my $IN, $infile);
open (my $OUT, '>', $outfile);
$/ = undef; ## allow entire input sequence file to be read into memory
my $text = <$IN>; ## read input sequence file into memory
print $text; ## output sequence file into new decoy sequence file
my @proteins = split (/>/, $text); ## put all input sequences into an array
for my $protein (@proteins) { ## evaluate each input sequence individually
$protein =~ s/(^.*)\n//m; ## match and remove the first descriptive line of
## the FATA-formatted protein
my $name = $1; ## remember the name of the input sequence
print $OUT ">REV$name\n"; ## prepend with #REV#; a # will help make the
## protein stand out in a list
$protein =~ s/\n//gm; ## remove newline characters from sequence
$protein = reverse($protein); ## reverse the sequence
while (length ($protein) > $NUM_C0L) { ## loop to print sequence with set number of cols
$protein =~ s/(.{$NUM_C0L})//;
my $line = $1;
print $OUT "$line\n";
}
print $OUT "$protein\n"; ## print last portion of reversed protein
}
close ($IN);
close ($OUT);
print "done\n";
答案 0 :(得分:2)
这将按照您的要求进行
它从FASTA文件中构建哈希%fasta
,保持数组@keys
以保持序列顺序,然后打印出哈希的每个元素
序列的每一行在添加到散列之前使用reverse
反转,并使用unshift
以相反的顺序添加序列的行
程序期望输入文件作为命令行上的参数,并将结果打印到STDOUT,可以在命令行上重定向
use strict;
use warnings 'all';
my (%fasta, @keys);
{
my $key;
while ( <> ) {
chomp;
if ( s/^>\K/REV/ ) {
$key = $_;
push @keys, $key;
}
elsif ( $key ) {
unshift @{ $fasta{$key} }, scalar reverse;
}
}
}
for my $key ( @keys ) {
print $key, "\n";
print "$_\n" for @{ $fasta{$key} };
}
>REVseq1
GFEDCBA
>REVseq2
NMLKJIH
如果您希望重新包装序列以便最后使用短行,那么您只需要重写转储哈希的代码
此替代方法使用原始文件中最长行的长度作为限制,并将反转序列重新包装为相同的长度。它的作者是指定一个显式长度而不是计算它很简单
您需要在程序顶部添加use List::Util 'max'
my $len = max map length, map @$_, values %fasta;
for my $key ( @keys ) {
print $key, "\n";
my $seq = join '', @{ $fasta{$key} };
print "$_\n" for $seq =~ /.{1,$len}/g;
}
鉴于原始数据,输出与上述解决方案的输出相同。我用它作为输入
>seq1
ABCDEFGHI
JKLMNOPQRST
UVWXYZ
>seq2
HIJKLMN
OPQRSTU
VWXY
有了这个结果。所有行都被包装为11个字符 - 原始数据中最长JKLMNOPQRST
行的长度
>REVseq1
ZYXWVUTSRQP
ONMLKJIHGFE
DCBA
>REVseq2
YXWVUTSRQPO
NMLKJIH
答案 1 :(得分:1)
我不知道这是否仅适用于使用玩具数据集或实际研究FASTA的类,其数量级为千兆字节。如果是后者,那么将整个数据集保存在内存中是有意义的,因为你的程序和Borodin都会这样做,但是一次只读一个序列,打印出来并将其忘记。以下代码执行此操作并处理may have asterisks as sequence-end markers的FASTA文件,只要它们以>
开头,而不是;
。
#!/usr/bin/perl
use strict;
use warnings;
my $COL_WIDTH = 80;
my $sequence = '';
my $seq_label;
sub print_reverse {
my $seq_label = shift;
my $sequence = reverse shift;
return unless $sequence;
print "$seq_label\n";
for(my $i=0; $i<length($sequence); $i += $COL_WIDTH) {
print substr($sequence, $i, $COL_WIDTH), "\n";
}
}
while(my $line = <>) {
chomp $line;
if($line =~ s/^>/>REV/) {
print_reverse($seq_label, $sequence);
$seq_label = $line;
$sequence = '';
next;
}
$line = substr($line, 0, -1) if substr($line, -1) eq '*';
$sequence .= $line;
}
print_reverse($seq_label, $sequence);