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

Hi, I have this script which scans a single directory for files older than five minutes. I'd like to expand its reach to scan a few directories on the same machine and to send the full path of the file name to the "warning.txt" file. Thanks for any ideas. Dave
#!/bin/perl -w use strict; open OUTPUT, ">c:/temp/warning.txt"; my $mytime=(time); my ($File,$FileStat,$CallOutDir); opendir(ROOT, ".") or die "Arghh!!! $!"; foreach $File (readdir(ROOT)) { next if $File=~/^\./; next if ($File eq "_Watched_Folder_._Active_"); next if ($File=~/\._Checking_File_Readiness_$/); if ($FileStat = (stat $File)[9]){ if ($FileStat <= ($mytime - 300)) { print "File older than 5min found. The file name is $File"; print OUTPUT "File older than 5min found. The file name is $Fi +le"; last; } } } close OUTPUT;

Replies are listed 'Best First'.
Re: Simple Multiple Folder Search Question
by matija (Priest) on Mar 22, 2004 at 15:40 UTC
    I suggest the following changes: after the my ($File... add the first line, and change the two following:
    foreach my $dir (@directories) { #@directories is your list of directo +ries opendir(ROOT,$dir) or die "Directory <$dir> failed: $!"; foreach my $F (readdir(ROOT)) { $File="$dir/$F";
    (and don't forget to close the outer loop at the end of your code).
      Thanks to both of you kind souls for the replies. Matija, I tried to alter my code according to your recommendations, but I keep getting a syntax error. Here is what the code looks like now:
      use strict; open OUTPUT, ">c:/temp/warning.txt"; my @directories = ('F:\Solimar_Work_Directories\XVTP\XVTP Cluster Feed +', 'G:\Solimar_Work_Directories\XVTP\XVTP Cluster Feed', 'G:\XVTPInpu +t', 'G:\XVTPInput\DBQA_input', 'G:\XVTPInput\DB_Input'); my $mytime=(time); my ($File,$FileStat,$CallOutDir); foreach my $dir (@directories) opendir(ROOT,$dir) or die "Directory <$dir> failed: $!"; foreach my $F (readdir(ROOT)) { $File="$dir/$F"; foreach $File (readdir(ROOT)) { next if $File=~/^\./; next if ($File eq "_Watched_Folder_._Active_"); next if ($File=~/\._Checking_File_Readiness_$/); if ($FileStat = (stat $File)[9]){ if ($FileStat <= ($mytime - 300)) { print "File older than 5min found. The file name is $File"; print OUTPUT "File older than 5min found. The file name is $Fi +le"; last; } } } } close OUTPUT;

      The error I get is:
      $ perl -c watchdir_revc.pl syntax error at watchdir_revc.pl line 18, opendir" watchdir_revc.pl had compilation errors.
        You probably figured out the syntax error by now, but in case you didn't: the first "foreach" loop (over "my @dir (@directories)") does not have an open curly brace. Fix that, and make sure the other braces are all properly balanced. This is a lot easier if you use a text editor that knows about programming languages (C-style indentation is good enough, but the really good programming editors, which provide syntax highlighting as well as automatic indentation, have a mode for editing Perl.)

        So long as you understand and trust the editor's automatic suggestions about how far indentation should go for a given line, it'll help you to know when and where to look for various brackets, braces, parens and quotes that happen to be missing or misplaced.

        Another problem I've run into is how to differentiate between folders and files when scanning these folders. I noticed that when I started testing this script it would count the sub-folders in its listing of things older than 5 minutes. I'd like to ignore folders completely.
        Is there some kind of regexp I can use in this
        next if $File=~/^\./;
        that would specify a folder to ignore? I'm looking all over for an answer to this and not getting anywhere. Thanks for any help.
Re: Simple Multiple Folder Search Question
by Happy-the-monk (Canon) on Mar 22, 2004 at 15:04 UTC
      Although it might be more elegant to do a find on the folders, for my purposes I'd actually just like to hard code the folders into the script (at present there are only 4 separate folders to scan), and just use the basic functionality of this script as it stands. I thought that adding more chdir 'C:/devl/bin/timedir' or die "Arghh!!! $!"; statements with the paths of each folder within it would do it, but I realized I was just chdir'ing into those directories and wasn't doing anything inside any of them (except of course for the last one in the list). Maybe I should create some kind of loop that will just do a single folder at a time, but I'm not sure my skill level will allow me to pull that off. Anyway, if I missed something about File::Find that I should know about, please give me a hint. Thanks, Dave

        What about doing:

        foreach my $dir ( @directories ) { chdir $dir; opendir( ... # your code goes here. }

        Sören