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

All,

I have a file named... uhh... lets call it desired_file.txt and there is a file with this same name in a directory path that is specific to the day of year it was created on. (yes i know this is a "hill-billy database i'm working with but it's what i'm stuck with so i have to deal with it......)

i.e. the path to a few of these are:

/home/myfiles/day_of_year/255/data/JPF_374362/desired_file.txt

/home/myfiles/day_of_year/256/data/EJF_264827/desired_file.txt

/home/myfiles/day_of_year/257/data/FFE_387392/desired_file.txt

...

/home/myfiles/day_of_year/###/data/desired_file.txt

respectively for days of year 255, 256, 257.

I have a foreach loop that is accessing an array where each element of that array contains the number for the day of year it wishes to access data for (and replaces ### in the path above to find the desired_file.txt for that day).

in the foreach, my script pulls the day of year from the array element in question, then attempts to open the "desired_file.txt" in the path associated with that day of year. the code is something like:

EDIT: putting in the actual code

<p>Okay, [actual code]:</p> <code> #!/tps/bin/perl -s my @day_of_year = (4257,4257,4258,4259); foreach (@day_of_year) { print"\nskimming for the day of year number:\n"; if ($_ =~ /(\d{4})/){ $day_of_year = $1; print "looking for things in $day folder /home/myfiles +/day_of_year/$day_of_year/*/desired_file.txt\n"; my $info_desired_filepath = glob('/home/myfiles/day_of +_year/'.$day_of_year.'/*/desired_file.txt'); print "$info_desired_filepath \t\t is the file name \n +\n"; <STDIN>; open ($info_FH, '<', $info_desired_filepath) or die "cannot open $info_desired_filepath.... +......\n\n"; print "found a file!!!!!!\n"; chomp(@lines = <$info_FH>); close($info_FH); } }

actual output:

skimming for the day of year number:

looking for things in 4257 folder /home/myfiles/day_of_year/4257/*/desired_file.txt

/home/myfiles/day_of_year/4257/JKY_63521/desired_file.txt is the file name

found a file!!!!!!

skimming for the day of year number:

looking for things in 4257 folder /home/myfiles/day_of_year/4257/*/desired_file.txt is the file name

cannot open ..........

end output

end edit

so what ends up happening is, the first time through, the script does exactly what i want. it find the file, opens it, munches on it and then goes back to the foreach for the next day of year value in the array. Thing is, the next time through, it die's saying it can't find the file.

Even if the first and second elements of the @days_of_year_array are THE SAME DAY OF YEAR, it works the first time but then the second time the print statement after the glob shows that $info_desired_filepath is empty.....

oh, and one last thing, i am using v5.8.3 built for sun4-solaris

HALP!

thanks folks
  • Comment on Globbing for file in an unkown directory path only works first time in foreach loop?
  • Download Code

Replies are listed 'Best First'.
Re: Globbing for file in an unkown directory path only works first time in foreach loop?
by Mr. Muskrat (Canon) on Jan 29, 2016 at 20:36 UTC

    Despite your updates, you still haven't shown us the code you are really running so I'm still not entirely sure what you are trying to accomplish but this should give you a push in the right direction.

    #!/bin/env perl use strict; use warnings; my @day_of_year = (4257,4257,4258,4259); # If @day_of_year only contains the days then there is no reason for m +atching for my $day_of_year (@day_of_year) { print "looking for things in $day_of_year folder /home/myfiles/day_o +f_year/$day_of_year/*/desired_file.txt\n"; # there may be multiple directories containing desired_file.txt my @desired_paths = glob('/home/myfiles/day_of_year/'.$day_of_year.' +/*/desired_file.txt'); for my $info_desired_filepath (@desired_paths) { print "$info_desired_filepath \t\t is the file name \n\n"; <STDIN>; open (my $info_FH, '<', $info_desired_filepath) or die "cannot open $info_desired_filepath..........\n\n"; print "found a file!!!!!!\n"; chomp(my @lines = <$info_FH>); close($info_FH); print "lines:\n"; print "$_\n" for @lines; # yep, we actually read the data } } __DATA__ Directory structure: myfiles/ day_of_year/ |-- 4257 | |-- a | | `-- desired_file.txt | |-- b | | `-- desired_file.txt | `-- c | `-- desired_file.txt |-- 4258 | |-- a | | `-- desired_file.txt | `-- c | `-- desired_file.txt `-- 4259 `-- c `-- desired_file.txt Output: skimming for the day of year number: 4257 looking for things in 4257 folder /home/myfiles/day_of_year/4257/*/des +ired_file.txt /home/myfiles/day_of_year/4257/a/desired_file.txt is th +e file name found a file!!!!!! lines: data /home/myfiles/day_of_year/4257/b/desired_file.txt is th +e file name found a file!!!!!! lines: data /home/myfiles/day_of_year/4257/c/desired_file.txt is th +e file name found a file!!!!!! lines: data bogus data skimming for the day of year number: 4257 looking for things in 4257 folder /home/myfiles/day_of_year/4257/*/des +ired_file.txt /home/myfiles/day_of_year/4257/a/desired_file.txt is th +e file name found a file!!!!!! lines: data /home/myfiles/day_of_year/4257/b/desired_file.txt is th +e file name found a file!!!!!! lines: data /home/myfiles/day_of_year/4257/c/desired_file.txt is th +e file name found a file!!!!!! lines: data bogus data skimming for the day of year number: 4258 looking for things in 4258 folder /home/myfiles/day_of_year/4258/*/des +ired_file.txt /home/myfiles/day_of_year/4258/a/desired_file.txt is th +e file name found a file!!!!!! lines: data /home/myfiles/day_of_year/4258/c/desired_file.txt is th +e file name found a file!!!!!! lines: data bogus data skimming for the day of year number: 4259 looking for things in 4259 folder /home/myfiles/day_of_year/4259/*/des +ired_file.txt /home/myfiles/day_of_year/4259/c/desired_file.txt is th +e file name found a file!!!!!! lines: data

    Updated: Added directory structure and output from my test run.

      Thank you Muskrat for your reply. I did infact include the actual code i was running, both in the reply to the post (Anonymous Monk on Jan 29, 2016 at 20:09 UTC) and in my edit to the OP. I've just had to change the directory paths/names to something else because of security/proprietary reasons.

      I'm going to try your implementation now but one thing that i'm concnerned about in your code is you have the comment: # there may be multiple directories containing desired_file.txt

      in the /home/myfiles/day_of_year/4257/ directory there are multiple folders. One of those folders (with unknown name) has a path that leads to the single file desired_file.txt.

      the directory structure looks something like

      /home/myfiles/day_of_year/255/data/JPF_374362/desired_file.txt

      /home/myfiles/day_of_year/256/data/EJF_264827/desired_file.txt

      /home/myfiles/day_of_year/257/data/FFE_387392/desired_file.txt

      where after the data directory there is a day specific ID (three letters, underscore, and then a bunch of numbers, all are unpredictable for each day) and within there is the file named desired_file.txt

Re: Globbing for file in an unkown directory path only works first time in foreach loop?
by toolic (Bishop) on Jan 29, 2016 at 19:32 UTC
    my $info_desired_filepath = glob('/home/myfiles/day_of_year/'.$day_of_interest.'/data/desired_file.txt');
    Since you only expect the glob to return 1 file, that line can be simplified as:
    my $info_desired_filepath = "/home/myfiles/day_of_year/$day_of_int +erest/data/desired_file.txt";
    the code is something like:
    Show your exact code. Reduce your code sample to narrow your problem down, if need be.

    Basic debugging checklist

Re: Globbing for file in an unkown directory path only works first time in foreach loop?
by Anonymous Monk on Jan 29, 2016 at 19:30 UTC
    prove it :) show that your story is true with code and output from that code
    #!/usr/bin/perl -- use strict; use warnings; use Path::Tiny qw/ path /; use File::Find::Rule qw/ find rule /; path( "goner/day_of_year/$_/data/desired_file.txt" )->touchpath for 1 +.. 3; print "$_\n" for find( file => name => 'desired_file.txt', in => 'gone +r' ); path( "goner" )->remove_tree; print "$_\n" for find( file => name => 'desired_file.txt', in => 'gone +r' ); __END__ goner/day_of_year/1/data/desired_file.txt goner/day_of_year/2/data/desired_file.txt goner/day_of_year/3/data/desired_file.txt

      Okay, actual code:

      #!/tps/bin/perl -s my @day_of_year = (4257,4257,4258,4259); foreach (@day_of_year) { print"\nskimming for the day of year number:\n"; if ($_ =~ /(\d{4})/){ $day_of_year = $1; print "looking for things in $day folder /home/myfiles +/day_of_year/$day_of_year/*/desired_file.txt\n"; my $info_desired_filepath = glob('/home/myfiles/day_of +_year/'.$day_of_year.'/*/desired_file.txt'); print "$info_desired_filepath \t\t is the file name \n +\n"; <STDIN>; open ($info_FH, '<', $info_desired_filepath) or die "cannot open $info_desired_filepath.... +......\n\n"; print "found a file!!!!!!\n"; chomp(@lines = <$info_FH>); close($info_FH); } }

      actual output:

      skimming for the day of year number:

      looking for things in 4257 folder /home/myfiles/day_of_year/4257/*/desired_file.txt

      /home/myfiles/day_of_year/4257/JKY_63521/desired_file.txt is the file name

      found a file!!!!!!

      skimming for the day of year number:

      looking for things in 4257 folder /home/myfiles/day_of_year/4257/*/desired_file.txt is the file name

      cannot open ..........

      end output

        Okay, actual code:

        close but but not quite

        See how I write code that first generates the requird files for the rest of the code to run?

        You don't actually want me to manually have to go create files do you?

        All that run tells me is that day 4257 doesn't have a file -- you say that is a problem, but how can I tell if the file really exists or not, other than you saying it does, but your code saying it doesn't?

        I don't think you have a file there