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

Hello there, long time reader first time poster. I've been learning perl slowly over the last few months and have some cool scripts that really help me at work. The script in question parses Wincross topline data for me and spits out an output file that tells me the bases. You don't need to know what any of that means because it does all that perfectly! The problem is that I'm having to specify which file I want it run on and that's silly because I only run it right after I create a file, so I just need it to run on my most recent rtf.
All I need is to replace:
open INPUT, "<8413at80.rtf";
I want it to simply use the most recently created rtf file in its current folder rather than "8413at80.rtf" or whatever. That's all. Running on a windows machine, the solutions I've found that seemed straightforward were for unix.
Thank you for your help!

Replies are listed 'Best First'.
Re: How to find most recent file and use it?
by johngg (Canon) on May 25, 2012 at 14:54 UTC

    Something like this perhaps?

    ... use List::Util qw{ max }; ... my %filesByAge = map { ( stat $_ )[ 9 ], $_ } glob q{*.rtf}; my $mostRecent = $filesByAge{ max keys %filesByAge }; ...

    It might not pick the particular file you want if you have a lot of RTFs created at exactly the same time but that sounds unlikely.

    I hope this is helpful.

    Cheers,

    JohnGG

      That did work, using
      open INPUT, "<$mostrecent"; after the code that you supplied!
Re: How to find most recent file and use it?
by RichardK (Parson) on May 25, 2012 at 15:00 UTC

    The file test operators -X -M will give you the modification time, so something like

    my $last = ( sort {-M $a <=> -M $b} glob('*.rtf') )[0];

    Do check the docs for glob, as it doesn't take a regex but a shell-like file match expression.

Re: How to find most recent file and use it?
by zentara (Cardinal) on May 25, 2012 at 16:10 UTC
    Here are a couple of File::Find scripts. The first is simpler and dosn't examine subdirs.
    #!/usr/bin/perl #check File::Find and note that the mtime #of a directory matches that of its newest file (for static files). #You can use the module File::Find to traverse the directory #structure and use stat to find the age of the file. The #example below sets up a hash data structure that contains #the name of the file and the last accessed modified time. #The application then compares the values in the hash and #prints out the newest file. use strict; use File::Find; use vars qw/%files/; sub findNewestFiles { my $element = $File::Find::name; return if (!-f $element); $files{$element} = (stat($element))[9]; } ####################################################### # MAIN ####################################################### my $dir = '/home/zentara/1down'; find(\&findNewestFiles, $dir); my $newestfile; my $time = 0; while(my ($k, $v) = each(%files)) { if ($v > $time) { $newestfile = $k; $time = $v; } } $time = localtime($time); print "The newest file is $newestfile : $time\n"; exit;

    A second more complex version

    #!/usr/bin/perl #check File::Find and note that the mtime #of a directory matches that of its newest file (for static files). #that is NEWEST not where the last file was modified(edited) #find the directory with the most recent modified time, #then use glob on that directory to find the most recent file. #That might be more efficient given the number of files and #directories that you are searching through because you would #only be storing directories in the hash and the application would #not be calling stat on all those files. #You can use the module File::Find to traverse the directory #structure and use stat to find the age of the file. The #example below sets up a hash data structure that contains #the name of the file and the last accessed modified time. #The application then compares the values in the hash and #prints out the newest file. use strict; use File::Find; my %dirs; my $dir = '/home/zentara/1down'; ####################################### find(\&findNewestdirs, $dir); sub findNewestdirs { my $element = $File::Find::name; return if (!-d $element); $dirs{(stat($element))[9]} = $element; } ###################################### my @times1 = sort { $a <=> $b } keys %dirs; my $tmax = pop @times1; my $newestdir = $dirs{$tmax}; #now find latest file in the latest dir my $lat_file; while (glob ("$newestdir/*")) { #for Access time, not creation time #$lat_file = $_ if ((-f) && (!defined ($lat_file) || -A $_ < -A $lat_f +ile)); $lat_file = $_ if ((-f) && (!defined ($lat_file) || -M $_ < -M $lat_fi +le)); } if (defined ($lat_file)) { print "latest_file is $lat_file\n"; } exit;

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: How to find most recent file and use it?
by locked_user sundialsvc4 (Abbot) on May 25, 2012 at 15:45 UTC

    It might also be useful to consider tools like File::Find::Rule and its brethren, to provide a more platform-independent and/or perhaps easier to modify approach to the task.   Sometimes you find code that contains “a set of chicken-scratches that works,” and your task is to modify it.   :-O!!   It therefore might be worth considering an approach that, from the outset, delegates the file-searching and/or selection process to an existing body of CPAN code with an eye toward long-term serviceability and maintainability.