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

I am converting text files into an HTML format to be posted on a web site. The names of the files are similar to this mlb_boxscore$283491230.txt. I am running triggers off my server that actually run the perl scripts that convert the files from text to html. The problem I have is that I have to open the file with it's exact name. This is a problem due to the fact I would have to change my code each day because I receive a new file every moring with a different name. The naming convention follows the format mlb_boxscore"some numbers". The following is what I am currently using to open the file:
open (INPUT, "c:/mlb_boxscore$283491230.txt") or die "Can't open file" +; open (boxscore, ">c:/boxscore" . $today . ".html") or die "Can't open +file"; open (HEADER, "c:/header.html") or die "Can't open file"; open (FOOTER, "c:/footer.html") or die "Can't open file";
I was wondering if there was anyway possible to open a file without specifying the exact name? Possibly something similar to open (INPUT, "c:/mlb_boxscore$_.txt") or die "Can't open file";. I know this doesn't work, I was just wondering if there was a way of doing something similar to this.

Replies are listed 'Best First'.
Re: Opening Text Files
by mpolo (Chaplain) on May 15, 2001 at 19:57 UTC
    What if you read the directory to get the actual filename? After parsing a file you could then move it to a different directory or delete it so that the next day the file that arrived would be the only one. I'm envisioning something like this:
    opendir DIR, "/path/to/mlb/incomingdir" || die "Open dir\n"; @filelist=readdir(DIR); closedir DIR; ## @filelist has all the files and directories in the given ## directory. You'll want to screen it to make sure you're ## opening a file. foreach (@filelist) { if (-f) { &parse_scorefile($_); &move_file_to_archive($_); } }
    You can actually compact this, doing the file check at the same time as the readdir, but I separated for clarity's sake. You'll of course want to strictify this.
Re: Opening Text Files
by arturo (Vicar) on May 15, 2001 at 19:48 UTC

    Here's a forehead-slapper: programming languages like Perl allow you to set variables ...

    open FILE, $filename or die "Can't open $filename: $!\n";

    So, get the name of the file into the script, perhaps by passing it as an argument on the command-line. Put the following near the top of the script to do this:

    my $filename = shift @ARGV or die "Usage: $0 filename\n";

    In fact, I often put filenames in scalars even for hard-coded filenames because if the name of the file ever changes, you only have to change it once.

Re: Opening Text Files
by dvergin (Monsignor) on May 15, 2001 at 19:52 UTC
    Yes. You are on the right track.

    What is needed is a clear statement of how you recognize which file to open. Is it the newest file? The file with the highest number in its filename? The only remaining file in its directory?

    Once we get that clear we can help you write some code to grab that particular file without hardcoding the filename in your script.

      The text file names will increase each time. For example, today's could be mlb_boxscore$0000100.txt and tommorow's will be mlb_boxscore$0000200.txt. The only thing that will change about the name of the file will be the numbers after the $. Hope this helps.
Re: Opening Text Files
by traveler (Parson) on May 15, 2001 at 20:13 UTC
    How about reading the directory, sorting the results and picking the "largest" one?
Re: Opening Text Files
by dvergin (Monsignor) on May 16, 2001 at 10:50 UTC
    Here's a complete solution to your problem. Assuming that the file that interests you is one of a group of files that are all in the form of mlb_boxscore$0000200.txt with the number portion 7 digits and zero-padded and the file you want always being the one with the hightest number, this will get you the name of the file you want:
    opendir DIR, "/path/to/mlb/incomingdir"; my ($todays_file) = reverse sort readdir(DIR); closedir DIR;
    If there are other files in the directory in question that we need to ignore, you'll need a little more:
    opendir DIR, "/path/to/mlb/incomingdir"; my ($todays_file) = reverse sort grep {/mlb_boxscore\$\d{7}\.txt/} readdir(DIR); closedir DIR;
    Now you can open $todays_file and process it as you like.

    Sorry about the funny formatting of the crucial line to get it to fit here. If you like in your own code you can lay it all down in one line thusly: my ($todays_file) = reverse sort grep {/mlb_boxscore\$\d{7}\.txt/} readdir(DIR);