Присвоение поиска регулярного выражения переменной: ошибка неинициализированной переменной
Я открываю файлы в каталоге, который содержит две строки последовательностей в каждом файле. Верхняя последовательность длиннее нижней, но включает нижнюю последовательность. Я хотел бы расширить нижнюю последовательность двумя боковыми буквами в каждом направлении, как только она будет найдена в верхней последовательности. Я пытаюсь сделать это путем сопоставления регулярных выражений, но получаю неинициализированную ошибку для переменной $ newsequence. Вот как выглядит типичный файл:
>CCCCNNNNNCCCC
NNNNN
Я хотел бы напечатать в одном файле все последовательности в следующем формате:
>CCCCNNNNNCCCC
CCNNNNNCC
Вот мой код до сих пор:
use strict;
use warnings;
my ($directory) = @ARGV
my @array = glob "$directory/*";
my $header;
my $sequence;
my $newsequence;
open(OUT, ">", "/path/to/out.txt") or die $!;
foreach my $file (@array){
open (my $fh, $file) or die $!;
while (my $line = <$fh>){
chomp $line;
if ($line =~ /^>/) {
$header = $line;
} elsif ($line =~ /^[CN]/) {
$sequence = $line;
}
my ($newsequence) = $header =~ /(([CN]{2})($sequence)([CN]{2}))/;
}
print OUT $header, "\n", $newsequence, "\n";
}
Как я могу улучшить свое регулярное выражение для $ newsequence, чтобы получить адекватный вывод? Благодарю.
2 ответа
Эта строка неверна:
my ($newsequence) = $header =~ /(([CN]{2})($sequence)([CN]{2}))/;
my
Ключевое слово создает новую переменную $newsequence
местный while
цикл, не назначая переменную в основном скрипте. Поэтому, когда вы пытаетесь написать $newsequence
после завершения цикла переменная все еще неинициализирована.
Либо положить print
заявление внутри while
цикл или удалить my
Ключевое слово в этом назначении.
Кроме того, вы должны поместить этот оператор присваивания внутри elseif
блок. В противном случае вы попытаетесь использовать $sequence
прежде чем назначить его. Так что все это должно выглядеть так:
foreach my $file (@array){
open (my $fh, $file) or die $!;
while (my $line = <$fh>){
chomp $line;
if ($line =~ /^>/) {
$header = $line;
} elsif ($line =~ /^[CN]/) {
$sequence = $line;
($newsequence) = $header =~ /(([CN]{2})($sequence)([CN]{2}))/;
print OUT $header, "\n", $newsequence, "\n";
}
}
}
Если ваши условия точны (каждый файл содержит только 2 строки, а последовательность всегда находится в заголовке), вы можете сделать свой код намного проще, включая регулярное выражение:
for my $file (@array) {
open (my $fh, $file) or die $!;
chomp ((my $header, my $sequence) = <$fh>);
$header =~ /(..)$sequence(..)/;
print OUT "$header\n$1$sequence$2";
}