Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Delete Old Directories

by Anonymous Monk
on Oct 20, 2011 at 01:51 UTC ( [id://932539]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks!
I have a program that creates everyday a directory using today's date, I need to read these directories every day and if any is older than 45 days delete it. My question is what would be the best way to delete this directory, using its name of from its age? I only have so far this code to try something:
#!/usr/bin/perl -w use strict; use POSIX qw(strftime); my $current_dir = "/alldir"; my $dir_name = strftime("%Y%m%d",localtime(time)); # when this runs, it will create a new dir in alldir directory. unless(-e $current_dir."/".$dir_name or mkdir ($current_dir."/".$dir_n +ame, 0755)) { die "Unable to create $current_dir."/".$dir_name\n"; } print "\n"; #now open $current_dir and read its content deleting any directory old +er than 45 days opendir (DIR, $current_dir) or die "Couldn't open directory, $!"; while (my $file = readdir DIR) { next if $file=~/^\./; #unlink if -D $file > 45; print "$file\n"; } closedir DIR;

Thanks for the Help!

Replies are listed 'Best First'.
Re: Delete Old Directories
by Marshall (Canon) on Oct 20, 2011 at 02:19 UTC
    I will venture forth with some advice:

    1). Use gmt (UTC) - dealing with local time and DST vs regular time is a mess. Eliminate that by only using UTC. Convert to local time only for user presentation when necessary.

    2). Use a directory name format that is sortable by normal alphanumeric sort: YYYYMMDD if month is 1, then use 01. If day is 9, use 09. A date in this format can be compared and sorted against other dates using just a simple cmp instruction. Leading zeroes matter.

    3). I would only use the "easily visible stuff", ie, the directory name (probably an easily parse-able part of that name). Although you are going to be creating directories on the "right dates", etc. and the -M time, etc should be the same, go with the name of the file. We want to have things that happen in the most obvious way possible and the obvious ways for users to list the files work should work. Please pay attention to (1) and (2).

    I hope these 3 points will save you a lot of grief!

    So, each dir name should have an easy way to parse YYYYMMDD out of it. Calculate the oldest YYYYMMDD date as a string that you want to keep. Use string compares of the regex captured date string of the file/directory name to decide whether this file/directory should be kept or not.
    delete (this file/directory) if ($thisdate lt $oldestdate);

      All that make sense, but if I have in this directory other directories like:
      09052011 10152011 10162011 10172011 10182011 10192011 10202011
      How could I compare these dates from the directory names if they are 45 days older than today's date. With the dates above I would have to delete 09052011 directory because its 45 days older than today's date.
        Your date format is different from the proposed one. To make things easy, you should be using this one:
        20110905 20111015 20111016 20111017 20111018 20111019 20111020
        Then, just generate the string for the day 45 days ago and remove everything lesser.
        How to find what that days' date was? How yould you proceed without a computer? Would you calculate the date, or just have a look into a calendar?
Re: Delete Old Directories
by williams554 (Sexton) on Oct 20, 2011 at 12:53 UTC

    Hello, this is what I would do. Please see comments

    #!/usr/bin/perl use strict; my $older_than = 45; # my @dirs = #could be this depending then just foreach them my @files = </Users/somedir/*>; foreach my $filename (@files) { next unless (-d $filename); # this is only letting dirs get past if ( int( -M $filename) > $older_than) { #do something print"dir is old:$filename\n";#print what is deleted here. # test what you are going to delete #&erase_directory ($filename); # after test uncomment this #rmdir $filename; # after test uncommnet this } } sub erase_directory { my $directory = shift @_; my @files = <$directory/*>; foreach (@files){ unlink "$_"; } }

    good luck, Rob

      I'm trying with something like the code below, but I am not sure on line 31  if($file <= $exp_dir_date){... because if it create directories like: 20111020 20110901 20110920, it will not delete the 20111001. Is there a better way to accomplish this?
      Here is the code I am talking about:
      #!/usr/bin/perl -w use strict; use POSIX qw(strftime); use Date::Calc qw( Today Add_Delta_Days); # get todays date::: my $file_date = sprintf "%04d%02d%02d", Today(); my $current_dir = "alldir"; my $exp_dir_date = sprintf "%04d%02d%02d",Add_Delta_Days( Today(), -45 + ); my $dir_name = strftime("%Y%m%d",localtime(time)); # when this runs, it will create a new dir in alldir directory. unless(-e $current_dir."/".$dir_name or mkdir ($current_dir."/".$dir_n +ame, 0755)) { die "Unable to create $current_dir."/".$dir_name\n"; } print "\n**\n"; #now open $current_dir and read its content deleting any directory old +er than 45 days opendir (DIR, $current_dir) or die "Couldn't open directory, $!"; while (my $file = readdir DIR) { next if $file=~/^\./; if($file <= $exp_dir_date){ print "\nDELETE:::$file - $file_date - $exp_dir_date\n\n"; rmdir("alldir/$file"); #-------> remove directory }else{ print "\nOK:::$file* = $file_date - $exp_dir_date\n\n"; } } closedir DIR; print "\n\ndone\n";

        Give this a try

        #!/usr/bin/perl use strict; use POSIX qw(strftime); use Date::Calc qw( Today Add_Delta_Days); my $older_than = 45; # get todays date::: my $file_date = sprintf "%04d%02d%02d", Today(); my $current_dir = "alldir"; my $exp_dir_date = sprintf "%04d%02d%02d",Add_Delta_Days( Today(), -45 + ); my $dir_name = strftime("%Y%m%d",localtime(time)); # when this runs, it will create a new dir in alldir directory. unless(-e $current_dir."/".$dir_name or mkdir ($current_dir."/".$dir_n +ame, 0755)) { die "Unable to create $current_dir."/".$dir_name\n"; } print "\n**\n"; #now open $current_dir and read its content deleting any directory old +er than 45 days my @files = </$current_dir/*>; foreach my $filename (@files) { next unless (-d $filename); # this is only letting dirs get past if ( int( -M $filename) > $older_than) { print"dir is old:$filename\n";#print what is deleted here. # test what you are going to delete #&erase_directory ($filename); # after test uncomment this #rmdir $filename; # after test uncommnet this } } sub erase_directory { my $directory = shift @_; my @files = <$directory/*>; foreach (@files){ unlink "$_"; } }

        Good luck, Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://932539]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (8)
As of 2024-04-18 16:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found