Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

deleting oldest file 1

Status
Not open for further replies.

nfaber

Technical User
Oct 22, 2001
446
US
I have an HPUX system that I runs a backup command via a perl maintenance script I wrote every week via cron. It creates a backup file in the /tmp directory. I want to only have 3 weeks worth of backups in the directory (all there is room for, all I need) so currently every week after it runs, I manually delete the oldest backup file. I want my maintenance script to do this for me. My problem is an easy way to determine the oldest file to unlink it.

Here is my code so far:

#!/opt/perl/bin/perl -w

use strict;
use File::stat;
use Compress::Zlib;

use vars qw($dirname @allfiles $file $day $month $year $created $stat $temp $time $junk $junk2);

$dirname = "/OV_backup"; # This is a directory where data can be found
opendir(DIR,"$dirname");
@allfiles = readdir DIR;
foreach $file (@allfiles) {
next unless ($file =~ /^OV_BACKUP_\d+/);
$stat = stat("$dirname/$file") or die "Can't stat $file: $!";
$created = $stat->mtime;
$time = localtime($created);
($junk,$month,$day,$junk2,$year) = split(/\s+/,$time);


print "$month\n$day\n$year\n";
}


My problem is how do I do a &quot;<&quot; &quot;>&quot; and account for the times when the oldest file is at the end of the month and therefore the day is greater than the newer ones? I am thinking about somehow creating an array of hashes and referencing it that way but:

1) I am not that good at perl
2) I think there may be an easier way.

Thanks so much
 
This little piece of code will look at the age of the file. If it is older than 21 days (3 weeks) it will stuff it in an array and then you can do what you like with it.

use warnings;
use strict;
use File::Find;
my @over21days;
find (\&wanted, &quot;$dir&quot;);
sub wanted {
/\.pdf$/ or return; # Replace .pdf with whatever pattern you desire
push @over21days, $File::Find::name if (-M $File::Find::name > 21); # Place in array if older than 21 days
}
print @over33days;
 
Thanks for the reply raklet, however that is not exactly what I am looking for. What I want to do it delete the oldest of the three files, not all files over 21 days old. What if we get in a senario (admittedly infrequently) when the system is down for some reason, or the OS is being upgraded etc. and a backup is not performed that week. Then there would be 2 files older than 21 days and I would loose one of my backups.

I hate to be picky when I am asking for advice, however I would like to get it right the first time.

Thanks Again.
 
No, problem. I didn't understand that you only had three files and wanted to get rid of just the oldest. The code can be modified to look like this.

use strict;
use File::Find;
my %info;
find(\&wanted, &quot;c:/temp&quot;);
sub wanted {
-f and $info{-M $File::Find::name}= $File::Find::name;
}
my @files;
foreach (sort {$a <=> $b} keys %info) {
push @files, $info{$_};
}

my $delete = pop @files;
print &quot;The file to be deleted is $delete with an age of &quot;,-M $delete,&quot; days.&quot;;
 
Ok raklet, excellent! seems to work, not that I know exactly what it happening, but I'll chew on it. Interesting....I just got a book in the mail at my desk called &quot;Perl, I Didn't Know You Could Do That&quot; and a variant of your script is in it.

One questions though. I only want to delete files that pass the following regex:

next unless ($file =~ /^OV_BACKUP_\d+/);

Where do I put the regex in your script?

Thanks again.
 
Should go here...

Code:
sub wanted {
    if( -f and $File::Find::name =~ /^OV_BACKUP_\d+/){
       $info{-M $File::Find::name}= $File::Find::name;
    }
}
 
Thanks for the reply Ho11ywood, however it does not seem to be working. My code is below and it give's me this output:

&quot;The file to be deleted is with an age of days.&quot;

Here is my code:

#!/opt/perl/bin/perl

use strict;
use File::Find;

use vars qw($info $File %info @files $delete $file);
my %info;
find(\&wanted, &quot;/OV_backup&quot;);

my @files;
foreach (sort {$a <=> $b} keys %info) {
push @files, $info{$_};
}

my $delete = pop @files;
print &quot;The file to be deleted is $delete with an age of &quot;,-M $delete,&quot; days.&quot;;

sub wanted {
if( -f and $File::Find::name =~ /^OV_BACKUP_\d+/){
$info{-M $File::Find::name}= $File::Find::name;
}
}



As always, any help is appriciated.
 
If you will look at the original code, you will see a comment that says where to place your regex. Here is the original code with bold letters.

use warnings;
use strict;
use File::Find;
my @over21days;
find (\&wanted, &quot;$dir&quot;);
sub wanted {
/\.pdf$/ or return; # Replace .pdf with whatever pattern you desire
push @over21days, $File::Find::name if (-M $File::Find::name > 21); # Place in array if older than 21 days
}
print @over33days;


Here is what your statement would look like:

use warnings;
use strict;
use File::Find;
my @over21days;
find (\&wanted, &quot;$dir&quot;);
sub wanted {
/^OV_BACKUP_\d+/ or return;
push @over21days, $File::Find::name if (-M $File::Find::name > 21); # Place in array if older than 21 days
}
print @over33days;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top