Ankur
Ankur

Reputation: 307

How to find few minutes older files in perl

I only want to process files which are last modified 10 minutes ago. I am trying to achieve it like this.

for my $file (<${dir}/*csv>_) { 
    if ( -M $file < .0069 ) {
        next;
        }
    else {
         code ...
          }
    } 

.0069 days have been counted for 10 minutes (10/ (24*60)). Now files present in the directory which are older than 1 day are identified correctly but any file which is less than 1 day older is recognized incorrectly. for example if file is 23 hours older it is getting processed in if block rather than else. I guess '-M $file' converting its value to integer (i.e. 0 in this case). Can anyone help here? Thanks

Additional: Thanks all. I am now trying with file::Stat

for my $file (<${dir}/*csv>_) { 
    my $mtime = (stat($file))[9];
    my ctime = time;
    my $time_diff = $ctime - $mtime;

    if ( $time_diff < 600 ) {
        next; }
    else {
        code ...
          }
    }

But this is not provoding the accurate results. For file just created $time_diff must be almost zero but it is coming out to be somewhere around -17640. I guess epoch shouldn't be any issue as both times are calculated since epoch. Where I wrong? ( server time is following IST (+5:30 hrs)

} 

Upvotes: 0

Views: 1645

Answers (3)

Erik Bennett
Erik Bennett

Reputation: 1089

Most Linux installations which include perl probably have the more generalized find2perl program.

Upvotes: 0

Georg Mavridis
Georg Mavridis

Reputation: 2331

Your code actually works: Trying

for my $file (<*>) { 
  print "File $file\n\t -M: " . (-M $file );
  if ( -M $file < .0069 ) {
     print " Doesnt fit\n";
     next;
  } else {
      print " Fits\n";
  }
} 

in my /tmp directory returned:

File config-err-GBOOnR
     -M: 0.0935532407407407 Fits
File cvcd
     -M: 0.0938425925925926 Fits
File kde-gm
     -M: 0.0935300925925926 Fits
File ksocket-gm
     -M: 0.0935300925925926 Fits
File orbit-gm
     -M: 16608.367650463 Fits
File unity_support_test.0
     -M: 0.0935532407407407 Fits

But you can also use stat instead:

my $mtime = stat($file)[9];
if(time-$mtime > 10*60) {
}

should do the job. See

perldoc -f stat

Upvotes: 0

user3967089
user3967089

Reputation:

The code as written should work. There are a few possible reasons why it doesn't. One is of course the familiar old floating point inaccuracy, but that should only hit times close to the ten-minute limit. Another one, which I think is more likely, but you don't give enough context to say for sure, is that the -M operator returns differences between the file timestamp and the time when the script started running. This means, for example, that any file created after the script was started will get a negative value from -M. If your script is long-running, -M is pretty useless. If the filesystem your files reside on is a remote one (NFS or something), clock discrepancy between the server hosting the file system and the server running your script can also mess things up.

I suggest that you rewrite your code to use stat() directly. That way you get the times in seconds, so you can deal with integers instead of floats, and you can compare against the current time instead of script start time. Have a look at perldoc File::stat to make using stat() a bit more readable.

Upvotes: 1

Related Questions