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

Monks,

I am looking at a directory that gets files delivered to it for processing. Each file is named uniquely but always has the extension ".DAT".

I need to monitor this directory and ensure that the oldest file is picked up within 300 seconds or report an error.

My script below only works if I give it a specific filename ($files) and I cannot for the life of me work out how to get the script to work with any file that is a ".dat"!!!

I think I am using a sledgehammer to crack a nut and would love it if someone could point me in the right direction, especially if it is a complete re-write to a simpler method!

Here's the code:

#!/bin/perl #################### # Subroutines #################### #################### # Declarations #################### # Use the File Statistics Module use File::stat; # Global Variables $tag=0; ################ # Get The Date ################ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); $year += 1900; $mon += 1; # If month is single digit add 0 if($mon < 10) { $mon = 0 . $mon; } # If day is single digit add 0 if($mday < 10) { $mday = 0 . $mday; } # If sec is single digit add 0 if($sec < 10) { $sec = 0 . $sec; } # If minute is single digit add 0 if($min < 10) { $min = 0 . $min; } # Get part of the year $years=substr($year,2,2); ############## # File Paths ############## $drive="PATH HERE"; $compfile="D:\\SERVERANDDIR\\compare$mday$mon$years.txt"; # Files $files=('20050718_0000585.DAT'); #################################################### # Check if its a Bank Holiday, if so exit the system #################################################### # Set Todays Date $tdate = "$mday-$mon-$year"; if( -e "D:\\SERVERANDDIR\\holidays.txt") { open(HOL, "D:\\SERVERANDDIR\\holidays.txt"); }else{ exit; } while(<HOL>) { $holine = $_; chomp $holine; if($tdate eq $holine) { close HOL; exit; } } close HOL; ######################## ## File Flow Script ## ######################## # Check if any of the drive is available - if not exit if( -e $midasdrive) { # Get the date stamp for the file }else { print "No directory listing \n"; exit; } # Check to see if any of the files exist in the Input directory foreach $filename($files) { if( -e "$drive$filename") { use Time::localtime; $datestring = ctime(stat("$drive$filename")->mtime); # Check to see if compare file exists if( -e $compfile) { # If Compare File exists check to see if that filename al +ready exists in the compare file open(CMP,"$compfile"); while(<CMP>) { # Does that filename exist Check for that filename in th +e ($line) = $_; chomp $line; # Check for the if($line eq "$filename $datestring") { # Then raise the alarm # samefile($filename); system("DO THE EMAIL THING HERE"); $tag=1; } # Else go to the next record in the file next; } # close the CMP file in read mode close CMP; # Thus there is stuff in the compare file but not this recor +d so lets add it to the existing file if($tag=0) { open(CMP,">> $compfile"); print CMP "$filename $datestring\n"; close CMP; } } # Create a New Compare File else { open(CMP,"> $compfile"); print CMP "$filename $datestring\n"; close CMP; } # End of the check to see if that filename exists } # End of the foreach statement - for filenames

READMORE tags added by Arunbear

Replies are listed 'Best First'.
Re: Test files not being processed
by davorg (Chancellor) on Jul 20, 2005 at 13:23 UTC

    Your scalar variable called $files should probably be an array called @files. You can populate it by using the "glob" function.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Test files not being processed
by tcf03 (Deacon) on Jul 20, 2005 at 13:42 UTC
    readdir and grep would be helpful here.

    Ted
    --
    "That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
      --Ralph Waldo Emerson
Re: Test files not being processed
by bofh_of_oz (Hermit) on Jul 20, 2005 at 15:32 UTC
    Firstly, do you have a timestamp in the name of those files? If so, you can use glob and regex the filenames...

    If not, you can use this:

    use strict; use warnings; use File::Glob; my $path = ""; my ($oldest, $fname) = (time, ''); my $modtime; chdir $path; foreach (glob("*")) { if (-f) { $modtime = (stat($_))[10]; ($oldest = $modtime and $fname = $_) if ($oldest > $modtime); } } print "$fname\t$oldest\n"; (abs(time() - $oldest) < 300) ? print "File recent enough\n" : print "Reporting an error\n";
    This will go through files in a directory ($path), find the oldest file, check if it was modified (created or overwritten) within last 300 seconds... the rest insert accordingly.

    --------------------------------
    An idea is not responsible for the people who believe in it...

      Hurrah for bofh_of_oz! I had been re-working the script to regex the timestamp but I think your code is much more succinct and reusable.

      I not only now love PERL (only been playing for three weeks), I also love this forum.

      Thanks to ARUNBEAR for the READMORE tags, I shall use them in future.
      I think the above will help me to see if new files are being written to my server, but I do not understand how $oldest is the oldest file.
      I need to know that the newest file was modified in the last ten minutes, so could someone explain the logic so I can hack this code myself?
      Thanks Monks . . .