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

Replies are listed 'Best First'.
Re: del files that is 7 days or older
by THRAK (Monk) on Feb 15, 2001 at 01:08 UTC
    Assuming you don't have a huge list of files to delete, this should be a reasonable approach. A couple of things...avoid system and backtick calls if you can do it easily within.
    #!/usr/bin/perl -w use strict; my $del_dir = "/directory/location/of/files"; my $del_days = 7; #delete files that are X days old my $now = time(); my $del_date = $now - (86400 * $del_days); #current date - (second per + day * days) my @dir_list; chdir $del_dir; opendir(DH, $del_dir) or die "Unable to read $del_dir directory. ERRO +R: $!\n"; @dir_list = grep { /(txt)$/ } readdir(DH); #build list of files that m +atch "txt" extension closedir(DH); foreach (@dir_list) { my ($file_time) = (stat($_)) [9]; # unlink $_ if ($del_date > $file_time); print "If the above was not commented out, $_ would have been dele +ted!\n"; }
    -THRAK
Re: del files that is 7 days or older
by yakko (Friar) on Feb 15, 2001 at 00:55 UTC
    On a cursory glance, I'd say you want to use File::Find, and find2perl

    Once you peruse the docs, you can run a regular find using find2perl:

    find2perl . -type f -mtime +7 -maxdepth 0 -exec rm {} \;
    This will give you perl code that you can use to perform the find using perl. You can tweak the options as needed to find the files you want.

    Another way is to use glob() and then test the mtime to see if the file's not been modified in the last week:

    if(-M $file > 7.0) { unlink $file; }
    (Update: for finding in a single dir, merlyn's answer is most likely not only shorter, but better. tis what I get for lagging in posting. The -M stuff would still apply, I think.:o)

    --
    Me spell chucker work grate. Need grandma chicken.

Re: del files that is 7 days or older
by mr.nick (Chaplain) on Feb 15, 2001 at 01:11 UTC
    This might be sacrilege, but this really isn't something suitable for Perl. Or, should I say, there is a better solution (since it appears you are using *Nix):
    #!/bin/sh /usr/bin/find /home/archive/logs/old -type f -mtime +7 -exec rm -fv {} + \;
    just the sort of thing find was made for.
      Then simply turn it into a Perl program!
      $ find2perl /home/archive/logs/old -type f -mtime +7 -exec rm -fv {} \ +; >myprog $ chmod +x myprog $ ./myprog
      Of course, you can tweak it to use fewer resources with
      $ find2perl /home/archive/logs/old -type f -mtime +7 -eval unlink >myf +asterprog

      -- Randal L. Schwartz, Perl hacker

        On my Linux 2.2 box, find2perl much less efficient than find itself
        nicholas@neko/3:(pts-0.neko) ~/noding > /usr/bin/time x 0.10user 0.03system 0:00.15elapsed 85%CPU (0avgtext+0avgdata 0maxresid +ent)k 0inputs+0outputs (356major+205minor)pagefaults 0swaps nicholas@neko/3:(pts-0.neko) ~/noding > /usr/bin/time find /usr0/Downl +oads -type f -mtime +180 -exec rm -fv {} \; 0.00user 0.00system 0:00.01elapsed 0%CPU (0avgtext+0avgdata 0maxreside +nt)k 0inputs+0outputs (96major+15minor)pagefaults 0swaps
        (obviously "x" is the output from find2perl). The exact same set of examples, when run on Solaris 2.6 on an Ultrasparc produces similiar results.
Re: del files that is 7 days or older
by djw (Vicar) on Feb 15, 2001 at 01:06 UTC
    I think you should check out File::stat to get all kinds of nice status information about files. You could setup a specific date you would like to have as your cut off date and then test it against the file creation date and delete if necessary. Here is a snippet:
    $set_time = 2592000; # 30 days in epoch time modify for taste $current_date = time; $create_date = stat($_)->ctime; if ($create_date < ($current_date - $set_time)) { # deletion stuff here }


    Hope this helps,
    djw
thank you all
by Anonymous Monk on Feb 15, 2001 at 05:01 UTC
    Thank you all for the help. thanks ^_^
Re: del files that is 7 days or older
by Pahrohfit (Sexton) on Feb 15, 2001 at 00:51 UTC
    To be real simple, instead of using the month/date/year approach, you could simply use epoch as your time refernce, and do some simple math to get your answer:
    #!/usr/bin/perl opendir(DIR, "/home/archive/logs/old"); @FileList = readdir(DIR); closedir DIR; $current_epoch = timelocal ((localtime)[0,1,2,3,4,5]); foreach $file (@FileList) { $file .= "/home/archive/logs/old" . $file; $file_epoch = (stat($file))[9]; if (($current_epoch - $file_epoch) > "604800") { unlink("$file); } }
    Or you could look at Date::Calc to do it your way.

    Update: merlyn, I noticed what I had typed and was changing as you were correcting me. Heh, I gotta be faster with the code checking next time.
      Ouch. No. Please, not:
      @FileList = `ls -1`;
      • The -1 isn't needed if the output is not a terminal.
      • This fails on filenames that contain newlines
      • This fails on non-Unix systems.
      • This fails if ls is not what you think it is.
      • This doesn't list the files that begin with dot, unless you're root.
      • You didn't chomp the list, so the names still end in newline.
      Much simpler:
      @FileList = <*>;
      Or, to get files that begin with dot:
      @FileList = <.* *>;

      -- Randal L. Schwartz, Perl hacker