Проблема в том, что вы продвигаетесь по файлу параллельно, поэтому, если в одном файле строка ">", в следующем может не быть ">".
То, как вы читаете данные в парах, например:
1: >0
2: >0
1: GAATAGATGTTTCAAATGTACCAATTTCTTTCGATT
2: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
1: >1
2: 40 40 40 40 40 40 40 40 15 40 40
1: GTTAAGTTATATCAAACTAAATATACATACTATAAA
2: >1
1: >2
2: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 20 40 40 40
1: GGGGCTGTGGATAAAGATAATTCCGGGTTCGAATAC
2: 40 40 40 40 40 40 40 40 40 40 40
1: EOF
2: >2
1: EOF
2: 40 40 40 40 7 40 40 5 40 40 40 40 40 40 40 40 37 13 31 20 15 40 10 11 4
1: EOF
2: 40 8 3 29 10 19 18 40 19 15 5
Тот же набор данных, примененный вашими правилами зацикливания, сделает это:
1: GAATAGATGTTTCAAATGTACCAATTTCTTTCGATT
2: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
1: GGGGCTGTGGATAAAGATAATTCCGGGTTCGAATAC
2: 40 40 40 40 40 40 40 40 40 40 40
Так что вам нужно либо отделить логику зацикливания, либо найти способ сопоставления файлов.
Вот попытка разделения поиска, но я не проверял его.
fileIO: {
while( 1 ){
my $seq;
my $qual = q{};
while( 1 ){
$seq = <SEQ>;
last fileIO if not $seq; # stop at end of file
last if $seq !~ /^>/;
}
while( 1 ){
my $qual_in = <PRB>;
last fileIO if not $qual_in; # stop at end of file
last if $qual_in =~ /^>/ and $qual ne q{};
next if $qual_in =~ /^>/ and $qual eq q{};
$qual .= $qual_in;
}
print "$seq \n $qual \n";
}
}
Обновление
Я повторно сгруппировал приведенный выше код в одну функцию, которая будет считывать порцию из произвольного дескриптора файла по мере необходимости. Заметьте, конечно, что я немного поэкспериментировал с трюком, который собирался использовать для чего-то практичного.
use strict;
use warnings;
#
# readUntilNext( $fileHandle, \$scalar_ref );
#
# returns 0 when nothing could be read from the fileHandle.
# otherwise returns 1;
#
sub readUntilNext {
my ($fh) = shift;
my ($output) = shift;
my ($output_buffer) = '';
while (1) {
my $line = <$fh>;
if ( !$line ) { # No more data
# No data to flush to user, return false.
return 0 if $output_buffer eq q{};
last; # data to flush to user, loop exit.
}
if ( $line =~ /^>/ ) {
# Didn't get anything, keep looking.
next if $output_buffer eq q{};
# Got something, flush data to user.
last;
}
chomp($line);
$output_buffer .= $line;
}
# Data to flush to user
# Write to the scalar-reference
$$output .= $output_buffer;
return 1;
}
open my $m, '<', 'a.txt';
open my $n , '<', 'b.txt';
# Creates 2 scalar references every loop, and only loops as long
# as both files have data.
while ( readUntilNext( $m, \my $seq ) && readUntilNext( $n, \my $qual ) ) {
print "$seq\t$qual\n";
}
И приведенный выше код, протестированный, делает именно то, что вы хотите сделать.
Обратите внимание на это \ мои вещи
while( readUntilNext( $m, \my $seq ) ) {
}
принципиально совпадает с
my $seq;
while( readUntilNext( $m, \$seq ) ) {
}
За исключением того факта, что первый каждый раз создает новый скаляр, гарантируя, что одно и то же значение не будет видно в последующем цикле;
так оно становится больше похоже на:
while( 1 ){
my $seq;
last if not readUntilNext($m, \$seq);
do {
# loop body here
}
}