in reply to Write to multiple files

Trying to guess which files you'll need beforehand is not a good idea. Here's a solution that opens the files you need on demand and closes them all at the end of the script.

#!/usr/local/bin/perl # multifileout.pl use strict; use warnings; my @file_ends = qw{./ .fasta}; my %handle = (); my @ko_array = qw(abc def ghi); while (<DATA>) { chomp; my ($head, $seq) = split / /; for my $ko (@ko_array) { if ($head =~ m/$ko/) { if (! exists $handle{$head}) { open my $fh, q{>>}, join($ko, @file_ends); $handle{$head} = $fh; } print { $handle{$head} } qq{$head\n$seq\n}; } } } map { close $handle{$_} } keys %handle; __DATA__ abc a123 def d123 abc a456 ghi g123 ghi g456 def d456

Here's the results:

ken@ganymede: ~/tmp $ ls -l *.fasta ls: *.fasta: No such file or directory ken@ganymede: ~/tmp $ multifileout.pl ken@ganymede: ~/tmp $ ls -l *.fasta -rw-r--r-- 1 ken staff 18 7 Feb 08:29 abc.fasta -rw-r--r-- 1 ken staff 18 7 Feb 08:29 def.fasta -rw-r--r-- 1 ken staff 18 7 Feb 08:29 ghi.fasta ken@ganymede: ~/tmp $ cat abc.fasta abc a123 abc a456 ken@ganymede: ~/tmp $ cat def.fasta def d123 def d456 ken@ganymede: ~/tmp $ cat ghi.fasta ghi g123 ghi g456 ken@ganymede: ~/tmp $

-- Ken

Replies are listed 'Best First'.
Re^2: Write to multiple files
by BrowserUk (Patriarch) on Feb 06, 2012 at 22:17 UTC

    You can simplify this: map { close $handle{$_} } keys %handle; to close $_ for values %handle;


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

Re^2: Write to multiple files
by jwkrahn (Abbot) on Feb 07, 2012 at 02:30 UTC
    while (<DATA>) { chomp; my ($head, $seq) = split / /;

    That would be better as:

    while ( <DATA> ) { my ($head, $seq ) = split;


    my @file_ends = qw{./ .fasta}; ... open my $fh, q{>>}, join($ko, @file_ends);

    With three argument open you don't need to prepend the file name with "./" and you should always verify that the file successfully opened before trying to use a possibly invalid filehandle:

    my file_end = '.fasta'; ... open my $fh, '>>', "$ko$file_end" or die "Cannot open +'$ko$file_end' because: $!";
Re^2: Write to multiple files
by julio_514 (Acolyte) on Feb 07, 2012 at 02:36 UTC
    Many thanks!:D It works fine now. I realized I could speed up thing modifying some code and using a hash. Here's what I came up with.
    my %handle = (); my $ref_db = FastaDb->new($fasta) or die("Unable to open Fasta file, $ +fasta\n"); while( my $seq = $ref_db->next_seq() ) { if($seq->header() =~ m/(K[0-9]{5})/){ my $ko = $1; if(!exists $handle{$ko}){ open my $fh, ">>".$outdir.$ko.".fasta"; $handle{$ko} = $fh; } print {$handle{$ko}} $seq->header()."\n".$seq->seq()."\n"; } } map { close $handle{$_} } keys %handle;