my %id2seq = (); # this is the verbose form of my %id2seq; my $id = ''; # this is the wrong place to declare this var! declare it when you need it ie # inside the while(){ block # missing the mode: put always even if it defaults to '<' open File,"human_hg19_circRNAs_putative_spliced_sequence.fa",or die $!; # better use lexical filehandle like in open my $fh, '<', $filepath or die # bareword is still accepted but by onvention is UPPERCASE so no open File... while(){ chomp; # here you are capturing something: if you want just the part before | you # have here the possibility to get it: /^>([\w\d]+\|)/ as starting option? if($_ =~ /^>(.+)/){ # or here: $id = $1; # cutting $1 like in: $id = (split /\|/, $1)[0] ... # AHHH! this is error! are your use strict; use warnings just make-up? # it must be foreach my $id .. # (or really does not raise a warn for the scope you given to $id ??? if so is even # worst!!) # in short: pay attention to the scope of your variables foreach $id (keys %id2seq){ # here the last good possibility to cut $id: # $id = (split /\|/, $id)[0]; if (-f $id){ # this is a lie.. print $id." Already exists, about to override it","\n" } # .. because you are going to append, not to overwrite open my $out_fh, '>>', "$id.fa" or die $!; # here parens are unneeded and probably nasty print $out_fh (">".$id."\n",$id2seq{$id}, "\n");