Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Finding Last minute file in a directory

by John007 (Acolyte)
on Aug 16, 2009 at 14:57 UTC ( #789020=perlquestion: print w/replies, xml ) Need Help??
John007 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I need to find the file created in last minute. I have sun solaris system which creates files called log_yy_mm_dd_hh_mm_ss.txt in a directory called mydir. I need to check for the file created in last minute and pull some data compare against set values and generate output.
I am having issue in identifying the last minute file. I can read files of that dir and compare with current time using localtime parameter as shown below but problem exists when time changes from ex. 7:59 to 8:00 or day changes at midnight i.e. script is non functional for a 1 minute period. I am looking for any unix commands/script or perl script whcih can give me last minute file. Though my file does have time stamp with its name. Thanks in advance
#!/usr/bin/perl use Data::Dumper; use Time::localtime; $year = (localtime -> year) + (1900); $mon = (localtime -> mon) + (1); $mday = localtime -> mday; $hour = localtime -> hour; $min = (localtime -> min) ; opendir (DIR, $directory) or die $!; while (my $file = readdir(DIR)) { if ($file =~ /^\w{10,16}(.txt)$/i ) { $filename = $1; if (($year == $fyear) && ($mon == $fmon) && ($mday == $fmday) && ($ho +ur == $fhour) && ($min == ($fmin + 1))) { $myfile = $filename; } } }

Replies are listed 'Best First'.
Re: Finding Last minute file in a directory
by zwon (Abbot) on Aug 16, 2009 at 16:23 UTC

    This code will find the file modified less than a minute ago:

    use strict; use warnings; use 5.010; use File::Spec; my $dirname = '.'; opendir( my $dir, $dirname ) or die $!; my $file; while ( $file = readdir($dir) ) { last if ( stat( File::Spec->catfile( $dirname, $file ) ) )[9] + 60 + > time; $file = ''; } say $file;

    Alternatively (it depends on what you really need if that solution would fit you), if there's only log files in directory, you can get list of files, sort it, and use last file.

Re: Finding Last minute file in a directory
by CountZero (Bishop) on Aug 16, 2009 at 16:17 UTC
    The DateTime module allows you to subtract a datetime from another giving you a duration object. It takes care of all "edge" case (changes of months, time zones, DST, ...). Once you have the duration, object it is easy to check if it is less than a minute (hint: check out the DateTime::Duration->compare class method).


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Finding Last minute file in a directory
by ssandv (Hermit) on Aug 16, 2009 at 16:20 UTC

    First of all, you make 5 calls to localtime which has the potential to go very wrong (for instance, imagine if it's New Year's Eve and the first 3 calls happen before the clock strikes midnight and the last two happen after it).

    Basically, you're doing the conversion backwards. You want to convert all your times to single integers (using something like Time::Local) and then calculate whether they are close enough together.

    If you get stuck trying to do that, let us know how far you got and we can go from there.

Re: Finding Last minute file in a directory
by graff (Chancellor) on Aug 16, 2009 at 22:36 UTC
    Instead of depending on the file name to tell you how old it is, maybe you could use the age of the file as given by the "-M" function (read about it via perlfunc -f -X.

    Since the value returned by -M is in days, you have to know that 1 minute equals 0.0006944 days:

    #!/usr/bin/perl use strict; my $Usage = "Usage: $0 pathname\n"; die $Usage unless ( @ARGV == 1 and -d $ARGV[0] ); my $dir = shift; opendir( DIR, $dir ) or die "opendir $dir failed: $!\n"; my @newfiles = grep { -f "$dir/$_" && -M _ < 0.000694445 } readdir DIR +; printf( "Found %d new files at %s\n", scalar @newfiles, scalar localti +me ); print " " , join( "\n ", @newfiles ) . "\n" if ( @newfiles );
    (updated to be a little more accurate about the age limit -- .0007 was probably too loose.)

    Now, if there happens to a file that was created an hour (day, week, month, year) ago and was modified within the last minute (i.e. its content changed, by appending or altering data), it will be reported as "new" regardless of its name, along with any file that was actually created within the last minute. If you don't want that, then you'll need to fall back to checking the file names.

    (I tried the "-C" function as well, but on my macosx/BSD system, it behaved the same as "-M" -- still, you might test it under solaris to see if "inode change time" is different in some useful way from "modification time".)

    Note that -M reports file age relative to the time at which your script began running, so the length of time it takes to run the script has no effect on the results (the last file fetched from the directory will be judged by the same criterion as the first file, no matter how many files are in the directory).

Re: Finding Last minute file in a directory
by John007 (Acolyte) on Aug 16, 2009 at 16:40 UTC
    Dear Monks
    Thanks for your hlep. Could you please guide me with a code for date time function.
    I now understand the benefit of making a single call but I still have the issue in getting the actual file time stamp. Is there any other way I can get it, how about the mtime, atime function. Thanks
      Dear zwon,
      I ran your code, I only have perl 5.8 version so it errored out for that and it also gave me other problems.
      #!/usr/bin/perl use Data::Dumper; use Time::localtime; use File::stat; use Term::ANSIColor; use Net::FTP; use warnings; use File::Spec; my $dirname = '.'; opendir( my $dir, $dirname ) or die $!; my $file; while ( $file = readdir($dir) ) { last if ( stat( File::Spec->catfile( $dirname, $file ) ) )[9] + 60 + > time; $file = ''; }

        The only 5.10 feature I've used is say and you can replace it by print. I recommend you to use strict as it helps to prevent some errors. Do you have any other problems with my example?

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (10)
As of 2018-06-21 13:20 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (118 votes). Check out past polls.