Возможно, вы захотите увидеть Читать FASTA в Ha sh. Это та же проблема, и она очень близка к коду, который я написал до того, как прочитал. Кроме того, на CPAN есть модули, которые могут обрабатывать FASTA .
Я думаю, что вы хотите объединить последовательности, начинающиеся с одного и того же имени, без учета чисел. Последовательности не должны иметь внутренних пробелов. В своем коде вы постоянно добавляете пробелы. Вы даже присоединитесь к новой строке. Итак, вы go к доктору и говорите: «Моя рука болит, когда я делаю это», а доктор говорит: «Так не делайте этого». :)
Когда вы сталкиваетесь с проблемами такого рода, проверяйте результаты своих операций на каждом этапе, чтобы увидеть, получаете ли вы то, что ожидаете. Вот очень упрощенная версия программы, которая, я думаю, делает то, что вы хотите. Я удалил большую часть структуры данных, потому что они усложняют ваш процесс.
Короче, прочитайте строку и удалите новую строку в конце. Это один из источников вашей новой строки. Затем извлеките последовательность и объедините ее с предыдущей последовательностью. Когда вы join
с новыми строками, вы добавляете новые строки. Так что не делайте этого:
use v5.14;
use warnings;
use Data::Dumper;
my %alliloux = ();
while (<DATA>) {
chomp; # get rid of that newline!
s/>//g;
# now split on whitespace, but only up to two parts.
# There's no array here.
my( $name, $seq ) = split /\s+/, $_, 2;
# remove the numbers at the end to get the prefix of the
# name.
my $prefix = $name =~ s/\d+\z//r;
# append the current sequence for this prefix to what we
# have already seen.f
$alliloux{$prefix} .= $seq;
}
say Dumper( \%alliloux );
foreach my $base ( keys %alliloux ) {
say ">text $alliloux{$base}";
}
__DATA__
>name aaa
>name2 cccc
>name99 aattaatt
Вам не нужен промежуточный массив. Вы можете создать свою строку как вы go. Вам не нужно иметь все части, прежде чем вы это сделаете.
Теперь, чтобы выяснить, где вы можете пойти не так, сделайте немного сразу. Убедитесь, что вы извлекли правильную вещь. Это дескриптор для размещения символов вокруг переменных, которые вы интерполируете, чтобы вы могли видеть пробелы в начале или конце:
while (<DATA>) {
chomp; # get rid of that newline!
s/>//g;
my( $name, $seq ) = split /\s+/, $_, 2;
say "Name: <$name>";
say "Seq: <$seq>"
}
Затем добавьте еще один шаг и убедитесь, что он работает:
while (<DATA>) {
chomp; # get rid of that newline!
s/>//g;
my( $name, $seq ) = split /\s+/, $_, 2;
say "Name: <$name>";
say "Seq: <$seq>"
my $prefix = $name =~ s/\d+\z//r;
say "Prefix: <$prefix>";
}
Повторите этот процесс для каждого шага. Затем, когда вы пришли с вопросом, вы определили точку, где вещи расходятся. Вот та же техника в вашей программе:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
while (<DATA>) {
s/>//g;
my ($onoma, @seq) = split (/\n/, $_);
say "Onoma: <$onoma>";
}
__DATA__
>name aaa
>name2 cccc
>name99 aattaatt
Вывод показывает, что у вас никогда ничего не было в @seq
. Вы разделяете новую строку, но если вы не изменили конец строки по умолчанию, вы получите только новую строку в конце:
Onoma: <name aaa>
Onoma: <name2 cccc>
Onoma: <name99 aattaatt>
Теперь в @seq
нет ничего, поэтому такая строка join "\n", ">$onoma", @seq;
на самом деле просто join "\n", ">$onoma"
. Вы могли бы увидеть это с небольшой проверкой.