Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

How to open file inside loops with file names generated using an array?

by skooma (Novice)
on May 28, 2018 at 07:02 UTC ( [id://1215289]=perlquestion: print w/replies, xml ) Need Help??

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

I have a bunch of files in a folder.

file_1.1_2.1.txt, file_1.2_2.2.txt and so on.

I am reading those files and extracting the info from the file name file_<data1>_<data2>.txt. After getting the info it is assigned to array @data1 and @data2 . I only require files in this format, there are also other files which i dont need. I am trying open the files using foreach.
foreach my $dat1 (@data1){ foreach my $dat2 (@data2){ open (FH, "<", "file_$dat1\_$dat2.txt") or die "a horrible death $! +"; .....do something...... } }
If I run this I am getting error "No such file or directory." but running it outside the loop works. For Example.
open (FH, "<", "file_1.1_2.1.txt") or die "a horrible death $!";

Replies are listed 'Best First'.
Re: How to open file inside loops with file names generated using an array?
by choroba (Cardinal) on May 28, 2018 at 07:24 UTC
    Maybe the arrays don't contain what you think they should? Try printing the values to verify:
    for my $dat1 (@data1) { for my $dat2 (@data2) { my $filename = "file_$dat1\_$dat2.txt"; print "<$filename>\n"; open my $fh, '<', $filename or die "a horrible death $!"; } }
    Note the angle brackets around the filename, they should help you find potential whitespace. The most common mistake is a missing chomp.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      I have tried that. The file names are printing properly. The variables themselves independently also looks fine when printed. Also I can open these files when I loop them directly using the array like.
      open ( TEST, ">", "test.txt") or die "\n$!\n"; foreach my $var ( @file_list ) { print "\n$var\n"; open ( RL, "<", $var ) or die "\n$!\n"; while (<RL>){ print TEST $_; } }

        skooma:

        You missed one bit that choroba put in his code: He wrapped the filename in brockets (<>) so that whitespace at the beginning or ending of the line would be more obvious. I expect that he's thinking your code would print something like:

        <foo >

        instead of the expected:

        <foo>

        because you may have gotten your data from a file without remembering to chomp off the line endings.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: How to open file inside loops with file names generated using an array?
by Athanasius (Archbishop) on May 28, 2018 at 07:35 UTC

    Hello skooma,

    choroba got in ahead of me, but another possibility is that your nested loops are generating more filenames than you actually have files. In the example given, your array @data1 will contain 1.1 and 1.2, and the array @data2 will contain 2.1 and 2.2. But your nested loops will then generate four file names:

    file_1.1_2.1.txt file_1.1_2.2.txt file_1.2_2.1.txt file_1.2_2.2.txt

    Do all of these files exist in the folder? If not, that would explain the “No such file” errors.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: How to open file inside loops with file names generated using an array?
by haj (Vicar) on May 28, 2018 at 12:01 UTC
    If you are opening a bunch of files, it is a good idea to include the bad filename into the error message, like this:
    foreach my $dat1 (@data1){ foreach my $dat2 (@data2){ my $path = "file_$dat1\_$dat2.txt"; open (FH, "<", $path) or die "Error opening '$path': '$!'"; .....do something...... } }
Re: How to open file inside loops with file names generated using an array?
by Anonymous Monk on May 28, 2018 at 16:01 UTC
    It is often a good idea to use something like File::Find (there are many flavors of this) to first locate the files you want to change, putting the names into an array that you then loop through. Opening and manipulating files within a loop that is also finding them can cause problems in some environments.
      Opening and manipulating files within a loop that is also finding them can cause problems in some environments.

      wat? examples please

        It depends on the operating system, but a file-finder can skip file entries or see the same entry more than once ... a problem that is neatly avoided by completely scanning, say, a particular directory, then processing that list before moving on to the next one. (I have not looked closely at Perl's implementation of file-finders, but in other languages I noticed them doing this internally, and wondered why they did it that way.) Particularly if you are inserting, deleting, or renaming entries in the designated container, this approach can avoid a lot of messy problems.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-24 17:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found