Operating System - HP-UX
1827293 Members
3794 Online
109717 Solutions
New Discussion

Perl Code help to clean 7 days old log files

 
SOLVED
Go to solution
Antonio Cardoso_1
Trusted Contributor

Re: Perl Code help to clean 7 days old log files

Hi Raf,

Maybe do these simple shell lines meet your expectations to remove you old files. For example

dir=
logfile=
find $dir -name "*.log" -mtime +7 -exec echo deleting {} \; >> $logfile
find $dir -name "*.log" -mtime +7 -exec rm -f {} \; >> $logfile 2>&1

Also, if you actually need to perform other tasks in your perl script, you can also use the find inside your perl. Example:
my $dir=
my $ff = `find $dir -name "*.log" -mtime +7 ` ;
my @ff = split (/\n/,$ff);
foreach $ff (@files) {
unlink($ff);
}

James R. Ferguson
Acclaimed Contributor

Re: Perl Code help to clean 7 days old log files

Hi Raf:

Perhaps your senior colleague is a good teacher --- one who wants to challenge you. No matter, the philosophy is that there's always more than one way to do anything.

That aside, I used your last script to offer this variation:

use strict;
use warnings;
use constant MAXDAYS => 7;
use constant ONEDAY => ( 60 * 60 * 24 );

my $dir = "/var/tmp";
my $file;
my $age;

opendir(DH, $dir) or die "Can't open directory $dir: $!\n";

while (defined ($file = readdir DH)) {
next if $file =~ /^\.\.?$/; # skip . and .. directories
if (-T $file) {
$age = (time() - (stat($file))[9]) / ONEDAY;
if ( $age > MAXDAYS ) {
print "$file is OVER ", MAXDAYS, " days old\n";
} else {
print "$file is ", int($age), " days old\n";
}
}
}
closedir DH or die "Can't close $dir: $!\n";
1;

As you can see, I did a fair amount of surgery.

I eliminate using a logfile and let the output go to STDOUT. This lets you run your script and view, sort, filter and/or redirect as you need. This makes your script much more versatile.

Get in the habit of checking the results of file and directory opens and closes. The $! reports the system's reason for the failure.

You can see that the '-M' test to get a file's age in days is really easier in the case you have selected. stat() returns the file modification time in epoch seconds so we had to do our own computation based on the current time in epoch seconds.

If you want more granularity than day increments of age, then certainly this longer method of gaining a file's age is your choice.

The 'while defined' loop makes it clear that 'readdir' returns a filename until there aren't any more. To signal the end, an 'undef' value is returned.

Regards!

...JRF...
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hello James and Antonio,

Thanks for your quick response guys.

Antonio: your info is certainly helful but I don't really want to use 'find' in the script. Thanks for your help mate..

James: your explanation would certainly help me sort this out, I will now write a new code from scratch and will be using your script as a template. I will get back to you if I will have any question. I really feel comfortable with your comments and how you have tried to explain everything in detail..
Thanks again James and everyone else..

Cheers,
Raf

Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Hein and James,

I have written a new code with your help to clean logfiles older than 7 days, could you please modify my code so it prints files to a log file instead of printing it to standard and then deletes files older than seven days,.. below is my code

use strict;

my $today = time;
my $dir = '.';

opendir DIR, $dir or die "opendir '$dir':"
while (my $file = readdir DIR) {
next if -d "$dir/$file";
my $mtime = (stat "$dir/$file") [9];
if ($today - 86400 * 7 > $mtime) {
print "$dir/$file is older than 7 days\n";
}
}
closedir DIR;

#END

Could you please modify the above code so it prints the file to a log file instead of printing it to standard out before it deletes it..
H.Merijn Brand (procura
Honored Contributor

Re: Perl Code help to clean 7 days old log files

use strict;
use warnings;

my $past = time - 86400 * 7;
my $dir = '.';
opendir DIR, $dir or die "opendir '$dir':$!";
my @file = grep { ! -d $_ } readdir DIR;
closedir DIR;
open my $log, ">/tmp/logfile.log" or die "Logfile: $!";
for (@file) {
my $mtime = (stat $_)[9];
if ($mtime < $past) {
print $log "$dir/$_ is older than 7 days\n";
}
}
close $log;

But that's not really perlish.

use strict;
use warnings;

my $dir = '.';

open my $log, ">/tmp/logfile.log" or die "Logfile: $!";
opendir DIR, $dir or die "opendir '$dir':$!";
print $log map { "$dir/$file is older than 7 days\n" } grep { -f $_ && -M $_ > 7 } readdir DIR;
closedir DIR;
close $log;

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Merijn,

Thanks for your prompt response and help, I will be modifying my code and will use your script as a guide.

I will post you tomorrow to let you know how it goes....thanks again

Have a great day..

Cheers,
Raf
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Merijn, James,Hein and all,

Guys with your help I have written a perl code and it works like a charm...I'm also getting more comfortable with the language now....I appreciate your help guys...My email is ...farhanbiz@hotmail.com....

Send me an email guys so i can add you in my friends list....I'm in Australia, so if any of you visit Aussie don't forget your mate....Cheers Raf

Below is my code:


#!/usr/local/bin/perl

use strict;

my $TODAY = time;
my $DIR = '.';
my $wktime = 604800; # ie (86400*7)

#############################################################################
sub write_to_file

{
open LOGFILE, ">/var/spool/uv/test/fileout");
opendir DIR, $DIR or die "could not open directory: $!";
while (my $file = readdir DIR)
{
next if -d "$DIR/$file";
my $mtime = (stat "$DIR/$file")[9];
if ($TODAY - $wktime > $mtime)
{

print LOGFILE "$DIR/$file is older than 7 days...removing\n";

}
}
}

close LOGFILE;
close DIR;

###############################################################################
sub remove_old_files
{
opendir DIR, $DIR or die "could not open directory: $!";
while (my $file = readdir DIR)
{
next if -d "$DIR/$file";
my $mtime = (stat "$DIR/$file")[9];
if ($TODAY - $wktime > $mtime)
{
unlink $file;
}

}

}
close LOGFILE;
close DIR;
##################################################################################
Main:
{
write_to_file();
remove_old_files();
}
H.Merijn Brand (procura
Honored Contributor

Re: Perl Code help to clean 7 days old log files

I will not make specific comments about your coding style, but the way you wrote the script is the way you write a C program, not how you write perl.
Even if this was to be a HUGE project, which it isn't, perl is usually more brief and terse. Once you get the hang of it, terse code (note the word "code", not "comment") will only help you to maintain it easier and faster.

Micro-optimisation, like making the calculations yourself in

my $wktime = 604800; # ie (86400*7)

is a waste of time, effort and maintainability. The nanosecond that the compiler to calculate things for you like this is not weighing up to the obfuscation it brings in the code, even if you add the comment. Think about how much easier the script was to change if you wanted to change to 8 days.

You're also using labels that are unused (Main:). labels are not used that often in perl, and spotting one, makes you want to (re)browse the entire script to see why it is there in the first place.

In my last example, compare the brevity and simplicity of my second scriplet that uses the builtin -M, to the first example that uses the C style like code that you had, and then think about how you would change that in the future.

I would advice you to make your CODE more perlish and short, while explaining what you did that you had trouble with understanding in COMMENT blocks.

If my colleage would write this code, I would not accept it.

Enjoy, Have FUN! (well meant) H.Merijn
Enjoy, Have FUN! H.Merijn
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Merijn,

I appreciate your input. My script has lot of flaws and I really don't think that it can go in production.

At least with your guys help I'm getting the hang of it, I will try to improvise by indenting it, your code was fairly simple and good enough.

Once I will do more reading in perl, I will understand it more, but along the way your help would be much appreciated, as I wasn't comfortable before but really after reading your code and help, I'm getting the hang of it.

Have a great day
Raf