File::Find is definately your friend for this. I have a script that I run on a win2k server to purge all files older that 2 weeks.
Don't use this verbatum, but it should give you an idea of how to do what you're looking for. You're going to want to read up on File::Find and the _X file test operators to see what exactly I'm doing.
There's also some ugliness with the log file name so ignore that. It's something that I need to fix but it hasn't been important enough to worry about.
###################################################################
# purge_bp.pl
# Purges files older than 14 days
# Created by Rich Chiavaroli
# Last modified on 2/14/01
# Change Log:
# 2/5/01 - 2/7/01 Inital Creation
#
# 2/14/01 Fixed directory removal. All empty directories
# will now be removed
###################################################################
use strict;
use File::Find;
my ($logfile, $path,@dirlist, $i, $entry,
@ignore_list, $ignore_file, @contents);
# uncomment this line and set it to the drive the bypass is mapped to.
#$path = "h:/*";
$logfile = "bypass.log";
# ignore.txt should have root directory names on seperate lines.
$ignore_file = "c:/temp/ignore.txt";
open(IGNORE_FILE, $ignore_file) ||die "Can't open ignore file: $!\n";
@ignore_list = <IGNORE_FILE>;
close IGNORE_FILE;
chomp(@ignore_list);
open( LOGFILE, ">>c:/temp/$logfile");
printf LOGFILE ("%d/%d/%d - Log of Purged documents for %s\n\n", (loca
+ltime)[3,4], (localtime)[5] - 100, $path);
while (<${path}> ) {
if ( -d ) {
push(@dirlist, $_ . "/") if ok_to_purge($_, @ignore_list);
}
}
print LOGFILE "\n================================\n\n";
find ({wanted => \&process_file, no_chdir => 1, bydepth => 1 } , @dirl
+ist);
foreach $i (@dirlist) {
unless (@contents = <$i/*>) {
print LOGFILE "Directory $i empty - deleted.\n";
rmdir ($i);
}
}
close LOGFILE;
# Begin functions
#################################################
#################################################
# This sub is passed each file to be processes.
# Deletes all files older than 14 days along with empty
# directories.
#################################################
sub process_file {
my($name, @contents);
$name = $File::Find::name;
#change /'s to \'s for the attrib command on windows platforms
$name =~ s#/#\\#g;
print "$name\n";
if (!-l && -d _) {
unless (@contents = <$File::Find::name/*>) {
if (rmdir($File::Find::name)) {
print LOGFILE "Directory $name empty - deleted.\n"
+;
}
elsif ((!`attrib -R $name`) && (rmdir($File::Find::name)))
+ {
print LOGFILE "Directory $name empty - deleted(Read On
+ly).\n";
}
else {
print LOGFILE "ERR: Can't delete $name - $!\n";
}
}
}
else {
my ($mdate, $cdate, $logfile, $age, $size,
$max_age);
$max_age = 14;
$age = int(-M) < int(-C) ? int(-M) : int(-C);
if ($age > $max_age) {
$size = (-s);
if (unlink($File::Find::name) ) {
print "$File::Find::name, - $age days, $size \n";
print LOGFILE "$File::Find::name, - $age days, $size \
+n";
}
elsif ((!`attrib -R $name`) && (unlink($File::Find::name))
+) {
print LOGFILE "$File::Find::name, - $age days, $size (
+Read Only)\n\n";
}
else {
print LOGFILE "ERR: Couldn't delete $File::Find::name
+- $!\n";
}
}
}
}
###################################################
# Checks the directory to see if it's in the ignore file.
###################################################
sub ok_to_purge {
my ($purge, $i, $dir, @list);
$purge = 1;
($dir, @list) = @_;
foreach $i (@list) {
if ($dir =~ /^$path\/$i/i) {
print LOGFILE "Ignoring directory: $dir\n";
$purge = 0;
last
}
}
return $purge;
}
|