Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Finding a file by age (Newest First)

by ChuckularOne (Parson)
on Jun 04, 2004 at 17:16 UTC ( #361005=perlquestion: print w/replies, xml ) Need Help??
ChuckularOne has asked for the wisdom of the Perl Monks concerning the following question:

I'm was trying use File::Finder to find a filename that is the X oldest file that matches a starting string. (I failed miserably...)
So I abandoned that and am trying anything that might work...
Here's an example:
from the directory listing;
where the files were created in chronological order.

If I pass the parameters "te" and "2" it would return test1.

I'm running perl v5.6.0 built for aix.

This is the code I came up with so far. It will create a list based on the regex for the name and find the Xth file based on position in the list. I need that list to be in chronological order.

#! /usr/bin/perl -w $mask = $ARGV[0]; $position = $ARGV[1]; opendir(DIR,"."); my @files = grep { $_ ne '.' && $_ ne '..' }readdir DIR; closedir(DIR); foreach(@files) { if ($_ =~ m/^$mask/ig) { push(@result,$_) } } print "Your file is: ".$result[$position-1]."\n";
=====================(( U P D A T E ))=====================
Thanks to everyone for there input. I implemented Zaxo's
code and it does exactly what I need.

Thanks for the quick results.

Replies are listed 'Best First'.
Re: Finding a file by age (Newest First)
by Zaxo (Archbishop) on Jun 04, 2004 at 17:38 UTC

    The stat call returns a list with mtime at index 9. Here's an example. I use glob to get the directory contents, but your readdir works, too. I'll pitch in a Schwarzian Transform to reduce the load of stat.

    my @sorted = map { $_->[1] } sort { $b->[0] <=> $a->[0] } map { [ (stat)[9], $_ ] } glob('*'); { # diagnostic local $, = ' '; print @sorted; } my @results = grep { /^$mask/ig } @sorted; print "Your file is: ", $results[$position-1], $/;
    Having $b to the left in the sort comparison gives newest first.

    If $mask is given as a glob pattern instead of a regex, that can replace '*' in the glob call to remove the grep step. If the arguments come from the command line, your shell will do the glob for you, making @ARGV[1..$#ARGV] your filename list.

    Update: Improved version, quicker by sorting a smaller pool:

    my @candidates = grep { /^$mask/ig } glob('*'); my @sorted = map { $_->[1] } sort { $b->[0] <=> $a->[0] } map { [ (stat)[9], $_ ] } @candidates; print "Your file is: ", $sorted[$position-1], $/ if defined $sorted[$position-1];

    After Compline,

      Thanks Zaxo! This did exactly what I was looking for.
Re: Finding a file by age (Newest First)
by pbeckingham (Parson) on Jun 04, 2004 at 17:42 UTC

    How about:

    my @files = sort {(stat $a)[9] <=> (stat $b)[9]} glob "$mask*"; print $files[$position - 1], "\n";

Re: Finding a file by age (Newest First)
by sacked (Hermit) on Jun 04, 2004 at 17:40 UTC
    #!/usr/bin/perl -w + use strict; my( $mask, $position )= @ARGV; die "Usage:\n\t$0 MASK POSITION\n" unless $mask and $position and $position =~ /^\d+$/ and $position > +0; + opendir( DIR, "." ) or die "can't opendir '.' for read: $!"; my @files= do { my %h; sort { ($h{$b} ||= -M $b) <=> ($h{$a} ||= -M $a) } grep { /^$mask/o } readdir(DIR) }; closedir( DIR ) or warn "error closing dir '.': $!"; + print "Your file is: ", ($files[$position-1] || "not found"), "\n";
    This example uses the Orcish Maneuver to cache the results of the file test operator -M.

Re: Finding a file by age (Newest First)
by gsiems (Chaplain) on Jun 04, 2004 at 17:43 UTC
    Not familiar with aix, but if your 'ls' supports it then:
    my ($mask, $position) = @ARGV; print "Your file is: ".(grep {/^$mask/i} `ls -tr`)[$position-1];
      You might want to make that ls -Atr

      The PerlMonk tr/// Advocate
        In this example, I'd skip Perl altogether.
        ls -At| grep '^te' | head -2 | tail -1


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://361005]
Approved by monktim
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (None)
    As of 2017-09-22 02:57 GMT
    Find Nodes?
      Voting Booth?
      During the recent solar eclipse, I:

      Results (256 votes). Check out past polls.