readline () ошибка дескриптора неоткрытого файла в Perl

У меня возникли проблемы с исправлением ошибки в моем коде. Я пытаюсь заставить код читать входной файл и извлекать только то, что находится между []. Однако ошибка, которую я получаю, это readline() on unopened filehandle... Я не уверен, что я делаю неправильно здесь для дескриптора файла while ().

#!/usr/bin/perl
use warnings;

my $file = '';
my $newfile = '';
open($newfile, '>', 'newmyosin.fasta') or die "Can't create file", $!;
open($file, '<', 'myosin.fasta') or die "Can't open file", $!;

while(<$file>) {
        print;
        chomp;
        if ( $_ =~ /\[(.+)\]/ ) {
                $file = $1;
        }
}

Так, например:

Вот как будет выглядеть одна часть моего входного файла:

>gi|115527082|ref|NP_005954.3| myosin-1 [Homo sapiens] 
>gi|226694176|sp|P12882.3|MYH1_HUMAN RecName: Full=Myosin-1; AltName: Full=Myosin heavy chain 1; AltName: Full=Myosin heavy chain 2x; Short=MyHC-2x; AltName: Full=Myosin heavy chain IIx/d; Short=MyHC-IIx/d; AltName: Full=Myosin heavy chain, skeletal muscle, adult 1 [Homo sapiens] 
>gi|119610411|gb|EAW90005.1| hCG1986604, isoform CRA_b [Homo sapiens]
MSSDSEMAIFGEAAPFLRKSERERIEAQNKPFDAKTSVFVVDPKESFVKATVQSREGGKVTAKTEAGATVTVKDDQVFPM
NPPKYDKIEDMAMMTHLHEPAVLYNLKERYAAWMIYTYSGLFCVTVNPYKWLPVYNAEVVTAYRGKKRQEAPPHIFSISD
NAYQFMLTDRENQSILITGESGAGKTVNTKRVIQYFATIAVTGEKKKEEVTSGKMQGTLEDQIISANPLLEAFGNAKTVR
NDNSSRFGKFIRIHFGTTGKLASADIETYLLEKSRVTFQLKAERSYHIFYQIMSNKKPDLIEMLLITTNPYDYAFVSQGE
ITVPSIDDQEELMATDSAIEILGFTSDERVSIYKLTGAVMHYGNMKFKQKQREEQAEPDGTEVADKAAYLQNLNSADLLK
ALCYPRVKVGNEYVTKGQTVQQVYNAVGALAKAVYDKMFLWMVTRINQQLDTKQPRQYFIGVLDIAGFEIFDFNSLEQLC
INFTNEKLQQFFNHHMFVLEQEEYKKEGIEWTFIDFGMDLAACIELIEKPMGIFSILEEECMFPKATDTSFKNKLYEQHL
GKSNNFQKPKPAKGKPEAHFSLIHYAGTVDYNIAGWLDKNKDPLNETVVGLYQKSAMKTLALLFVGATGAEAEAGGGKKG
GKKKGSSFQTVSALFRENLNKLMTNLRSTHPHFVRCIIPNETKTPGAMEHELVLHQLRCNGVLEGIRICRKGFPSRILYA
DFKQRYKVLNASAIPEGQFIDSKKASEKLLGSIDIDHTQYKFGHTKVFFKAGLLGLLEEMRDEKLAQLITRTQAMCRGFL
ARVEYQKMVERRESIFCIQYNVRAFMNVKHWPWMKLYFKIKPLLKSAETEKEMANMKEEFEKTKEELAKTEAKRKELEEK
MVTLMQEKNDLQLQVQAEADSLADAEERCDQLIKTKIQLEAKIKEVTERAEDEEEINAELTAKKRKLEDECSELKKDIDD
LELTLAKVEKEKHATENKVKNLTEEMAGLDETIAKLTKEKKALQEAHQQTLDDLQAEEDKVNTLTKAKIKLEQQVDDLEG
SLEQEKKIRMDLERAKRKLEGDLKLAQESTMDIENDKQQLDEKLKKKEFEMSGLQSKIEDEQALGMQLQKKIKELQARIE
ELEEEIEAERASRAKAEKQRSDLSRELEEISERLEEAGGATSAQIEMNKKREAEFQKMRRDLEEATLQHEATAATLRKKH
ADSVAELGEQIDNLQRVKQKLEKEKSEMKMEIDDLASNMETVSKAKGNLEKMCRALEDQLSEIKTKEEEQQRLINDLTAQ
RARLQTESGEYSRQLDEKDTLVSQLSRGKQAFTQQIEELKRQLEEEIKAKSALAHALQSSRHDCDLLREQYEEEQEAKAE

Исходя из этого, я хотел бы создать новый файл «newmyosin.fasta», который выведет имя организма в скобках в заголовке для этого образца (например, [Homo sapiens]. Код Perl используется для чтения из файла myosin.fasta). файл с несколькими примерами, как указано выше, выберите имя в скобках [] и запишите в новый файл (например, newmyosin.fasta).

Спасибо!


person Elle    schedule 08.11.2015    source источник
comment
Вы устанавливаете свой дескриптор файла в пустую строку в начале, а затем переназначаете его строке в своем цикле. Не делай этого.   -  person Matt Jacob    schedule 08.11.2015
comment
Тогда что бы вы предложили мне сделать, чтобы исправить код?   -  person Elle    schedule 08.11.2015
comment
Используйте другую переменную для хранения результата совпадения с регулярным выражением. Я могу написать правильный ответ позже.   -  person Matt Jacob    schedule 08.11.2015
comment
Можете ли вы включить пример входных данных и ожидаемый результат? Ознакомьтесь с разделом Как создать минимальный, полный и проверяемый пример.   -  person Matt Jacob    schedule 08.11.2015
comment
Вытащить текст в скобках и поставить куда? Должны ли быть включены другие строки без скобок? Вы пробовали код, который я разместил в своем ответе?   -  person Matt Jacob    schedule 08.11.2015
comment
Вы никогда не должны получить эту ошибку с этим кодом. Если открытие не удается, программа должна умереть. Если нет, то он не открыт. Либо это не тот код, который вы использовали на самом деле, либо вы что-то из него удалили.   -  person TLP    schedule 08.11.2015
comment
Я хотел вытащить текст в скобках и записать его в новый файл, который я создавал. Нет, другие строки без скобок включать не следует. Да, я попробовал код, который вы разместили в своем ответе. Он не тянул то, что я хотел, чтобы он тянул. Я не смог заставить его правильно записать в файл.   -  person Elle    schedule 08.11.2015
comment
Кроме того, это весь код, который я использовал. Я не удалял и не редактировал его каким-либо образом.   -  person Elle    schedule 08.11.2015
comment
О, лол, я только что понял, что ты сделал это: $file = $1;, это нехорошо   -  person TLP    schedule 08.11.2015
comment
Отсутствует use strict;.   -  person melpomene    schedule 08.11.2015
comment
Без образца вывода невозможно узнать, что вы ищете. В общем, когда вы просите о помощи, вы хотите, чтобы другим людям было легко помочь вам, а не мучительно трудно.   -  person Matt Jacob    schedule 08.11.2015
comment
Возможный дубликат Как решить следующую ошибку readline() в неоткрытом дескрипторе файла...?   -  person jww    schedule 05.05.2019


Ответы (2)


Когда вы делаете это:

$file = $1;

Вы перезаписываете дескриптор файла. Тогда вы больше не сможете с него читать. И вы получите упомянутую ошибку.

Конечно, вы должны сохранить матч в другом месте, например:

my $match = $1;

И, вероятно, также распечатать его:

print $newfile $match;
person TLP    schedule 08.11.2015

Как я сказал в своем комментарии, вы повторно назначение вашего дескриптора файла группе захвата в середине чтения файла. Поскольку вы открыли отдельный файл для вывода, я предполагаю, что вместо этого вы хотите напечатать соответствующие строки в этот файл.

Сказав это, ваши требования довольно расплывчаты, ваш образец ввода не выглядит точным, и вы не предоставили образец вывода, но если я правильно понимаю ваше намерение, я думаю, что это то, что вы хотите:

my $file = 'myosin.fasta';
my $tmp = "$file.tmp";

open(my $new, '>', $tmp) or die "Can't open $tmp: $!";
open(my $old, '<', $file) or die "Can't open $file: $!";

while (<$old>) {
    if (/\[([^]]+)\]/) {
        print $new "$1\n";
    }
}

close($old);
close($new);

rename($file, "$file.bak");
rename($tmp, $file);

Содержимое myosin.fasta после запуска скрипта:

Homo sapiens
Homo sapiens
Homo sapiens
person Matt Jacob    schedule 08.11.2015