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

Hello, I'm a real newbie, and have a challenge in that I must include in a script deletion of files by date. I frequently use the DOS command: system ('del c:\newfiles\*.htm') There is no option in DOS to delete by date. How could this be accomplished in perl? Or can it? Thanks in advance for your advice!

Replies are listed 'Best First'.
Re: Deleting files based on date
by Zaxo (Archbishop) on Oct 20, 2003 at 01:49 UTC

    Here's one way,

    my $days = 30; for (glob '*') { unlink if -f and -M > $days; }
    That uses the file test operators to check if each name rperesents an ordinary file, and to see if the file is more than 30 days old. Adjust $days (can be fractional) for age, and the argument of glob for path and any specializations like file extension.

    After Compline,
    Zaxo

      I don't know why, but I find -M and friends confusing, because they work the 'wrong' way for my brane, by making older files have higher values, whereas stat and friends use epoch time and newer files have higher values. So I'd use stat like below. There's a little more code, but it's easier for me to read:
      unlink grep { (stat($_))[9] < time - ($days * 86400) } @files;
      where 86400 is the number of seconds in a day, so we unlink all files from the @files array where their modification time earlier than $days days old.
        ...I find -M and friends confusing, because they work the 'wrong' way for my brane...

        I agree, but for a different reason: the fact that calculations are done from script startup time can lead to unexpected results for long-running scripts, or when running under mod_perl.

        That's why I personally prefer to use stat() as well: changing $^T is too much "action at a distance" to me.

        On the other hand, being able to recognize 86400 as a synonym for a day, is a typicial sysadmin deformity to me ;-)

        Liz

Re: Deleting files based on date
by jonadab (Parson) on Oct 20, 2003 at 01:54 UTC
    There is no option in DOS to delete by date.

    It's possible to do this in DOS (or at the Windows command prompt, which I suspect is what you really mean) by combining some things, but it's actually easier to do it in pure Perl.

    for (<C:\\newfiles\\*.htm>) { unlink if (-M > $somenumberofdays); }

    This doesn't recursively traverse the directory structure, but you can do that also using readdir and/or the -d and/or -f file test operators. With readdir, it's even possible to do this in a cross-platform way without worrying about what character is the directory separator on your platform (backslash on DOS and Windows, slash on POSIX systems, colon I think on older MacOSes, and then there's VMS...) Also, I think $somenumberofdays doesn't have to be an integer, so you could delete files more than (say) twelve hours old by setting it to 0.5, unless I am mistaken. If you need to traverse the directory tree and need more help with it, post a reply here saying so.

    Like I said, it's possible to use backticks to shell out to COMMAND.COM and get this done with standard MS command-line tools, but it's the more difficult way to go. Since you already have Perl on the system, use it.


    $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
Re: Deleting files based on date
by pg (Canon) on Oct 20, 2003 at 01:25 UTC

    The easiest way is to use find2perl. If there is something available to you, what is the point to reinvent it ;-?

    If you are familiar with unix, this makes you feel back to home. It is similar to unix find command, and you will love it.

    It is a tool coming with Perl, you can find it under your perl bin directory. On Windows, it is a .bat file. Even on unix, you can use it, as find2perl is faster than the find command.

Re: Deleting files based on date
by chimni (Pilgrim) on Oct 20, 2003 at 05:31 UTC

    Hi
    you could even look into something as simple as:
    get absolute path of filename input
    use the stat command and slice the array subscript containg the file creation date.
    ctime File creation time (C lang. time_t value)
    then you could just remove all leading and trailing spaces from the date input and that received from stat.
    and do a
    if( $date =~ m/$date1/) { unlink file; }

    HTH
Re: Deleting files based on date
by PriNet (Monk) on Oct 20, 2003 at 06:12 UTC
    try the lstat(file)[10] function to get file creation date?


    you mean there's any easier way?

    Edited by castaway - added code tags.