Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

varaible to filehandle -alack!

by maayanster (Initiate)
on Oct 28, 2010 at 19:16 UTC ( [id://868125]=perlquestion: print w/replies, xml ) Need Help??

maayanster has asked for the wisdom of the Perl Monks concerning the following question:

Hi there, I'm trying to divide a file into several files based on part of each line:
#use strict; open ALUS, "Z:\\3\' UTR intron project\\Alu_bed.bed" ||die "couldn't o +pen alus!!"; my %seen; while (<ALUS>){ /(chr.*?)\t/; if (exists $seen{$1}){ print $1 "$_"; }else{ $seen{$1}="whatever"; open $1, ">Z:\\3\' UTR intron project\\Alu_chroms\\$1.txt"||di +e "couldn't open $1 file!"; print $1 "$_"; } }

Works when I comment out the use strict;, otherwise, I get the dreaded "Can't use string ("chr1") as a symbol ref while "strict refs" in use at divide_chroms_Alu.pl line 12, <ALUS> line 1."

I tried all sorts of things with curly braces and stars and slashes that I found in various threads on the interwebs, but I must be crazy, because I couldn't get them to work! and what the hell is a glob? advice?

Replies are listed 'Best First'.
Re: varaible to filehandle -alack!
by SuicideJunkie (Vicar) on Oct 28, 2010 at 19:27 UTC

    Three suggestions for your open:

    • Use the three argument version
    • Use lexical filehandles
    • Use or not || for control flow.
    open my $inputFH, '<', $pathToFile or die "Can't open $pathToFile for +reading. Reason given = $!\n"; open my $outputFH, '>', $pathToFile2 or die "Can't open $pathToFile2 f +or writing. Reason given = $!\n"; while ($line = <$inputFH>) { print $outputFH "Foo $line Baz\n"; }

    Edit: Writing to a file opened for reading was silly.

Re: varaible to filehandle -alack!
by Crackers2 (Parson) on Oct 28, 2010 at 20:19 UTC

    I suspect you want something like this:

    use strict; open my $ALUS, "Z:\\3\' UTR intron project\\Alu_bed.bed" or die "Coul +dn't open alus: $!"; my %seen; while (<$ALUS>){ /(chr.*?)\t/ or next; if (! exists $seen{$1}){ open my $fh, ">", "Z:\\3\' UTR intron project\\Alu_chroms\\$1.tx +t"||die "couldn't open $1 file!"; $seen{$1} = $fh; } print {$seen{$1}} "$_"; }
Re: varaible to filehandle -alack!
by choroba (Cardinal) on Oct 28, 2010 at 20:39 UTC
    Using $1 as a filehandle is dreadful. Use a plain variable.
    Also, setting the value of %seen to something smaller (like 1 or undef) can save you little memory if the file is big.
Re: varaible to filehandle -alack!
by johngg (Canon) on Oct 28, 2010 at 22:33 UTC

    You might be better off to use a lexical hash to hold your filehandles rather than $1. You also ought to cater for the possibility of lines that don't match your pattern. I have changed your pattern, substituting a negated character class ([^\t]+) for your non-greedy .*? as that is perhaps safer.

    In the code below I use a HEREDOC as my input and references to scalars (actually hash values) as my output just to avoid creating loads of files on my disk; the principle will work just as well with real files.

    use strict; use warnings; open my $alusFH, q{<}, \ <<EOD or die qq{open: << HEREDOC: $!\n}; chrabc123 blah blah chrdef456 burble blurgh Duff line to be rejected chrabc123 rootle tootle EOD my %seen; my %fileHandles; my %outputFiles; while ( <$alusFH> ) { if ( m{^(chr[^\t]+)\t} ) { do { open $fileHandles{ $1 }, q{>}, \ $outputFiles{ $1 } or die qq{open: > scalar ref.: \n}; } unless $seen{ $1 } ++; print { $fileHandles{ $1 } } $_; } else { warn qq{Bad line: $_}; } } close $alusFH or die qq{close: << HEREDOC: $!\n}; do { close $fileHandles{ $_ } or die qq{close: > scalar ref.: \n}; } for keys %fileHandles; print qq{$_:\n\n$outputFiles{ $_ }----------\n} for sort keys %outputFiles;

    Here's the output.

    Bad line: Duff line to be rejected chrabc123: chrabc123 blah blah chrabc123 rootle tootle ---------- chrdef456: chrdef456 burble blurgh ----------

    I hope this is of interest.

    Cheers,

    JohnGG

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://868125]
Approved by sierpinski
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2024-04-23 16:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found