Solved

Report old files

Posted on 2004-08-24
6
153 Views
Last Modified: 2010-03-05
Hi,

I'm having a bit of a trouble creating a Perl script.

The script, which is going to run on a Unix machine, is supposed to loop through a directory and report all directories whose files haven't been read or written to for the last month. However, if a directory contains sub-directories as well as files that directory should only be reported if the contents of the sub-directories are also too old. I'll give you an example:

Dir
    - Sub dir
        - file (which is more than a month old)
        - file (which is more than a month old)
   
    - Sub dir2
        - file (which is more than a month old)
        - file (HAS been accessed in the past month)
   
    - Sub dir3
        - file (which is more than a month old)
       
    - Sub dir 4
        - Sub sub dir
            - file (which is more than a month old)
            - file (which is more than a month old)
        - Sub sub dir 2
            - file (which is more than a month old)
Dir 2
    - Sub2 dir
        - file (which is more than a month old)
    - Sub2 dir2
        - file (which is more than a month old)  
    - Sub2 dir3
        - Sub2 sub dir
            - file (which is more than a month old)      
        - file (which is more than a month old)

After running the script the following should be printed:

Dir/Sub dir
Dir/Sub dir3
Dir/Sub dir4
Dir2

I know I have to do this recursively but I'm having great trouble ONLY reporting the directories which contents are too old.

Can anyone help with a solution?
0
Comment
Question by:Tchami
  • 2
  • 2
6 Comments
 
LVL 84

Accepted Solution

by:
ozo earned 500 total points
ID: 11888831
use File::Find;
our %old;
find(sub{
    if( -f ){
        my $path=\%old;
        my $old = -M > 30;
        for( grep length,split'/',$File::Find::dir){
            ++${$path->{$_}}{"."}[$old];
            $path=$path->{$_};
        }
    }
},".");
printold(each %old);
sub printold{
    my($p,$d)=@_;
    for( keys %{$d} ){
        next unless ref($d->{$_}) eq "HASH";
        if( $d->{$_}{"."}[1] ){
            if( $d->{$_}{"."}[0] ){
                printold("$p/$_",$d->{$_});
            }else{
                print "$p/$_\n";
            }
        }
    }
}
0
 

Author Comment

by:Tchami
ID: 11925868
Hmm, how do I change the "expiration date" from 30 days to say 1 minute?
0
 
LVL 84

Expert Comment

by:ozo
ID: 11927727
my $old = -M > 1/(24*60);
0
 

Author Comment

by:Tchami
ID: 11950434
That works perfect! Thanks a lot.

I'm sorry for being so slow to reply, but I've been away. Now I'm back and this has #1 priotity :)

I'm trying to figure out how the code works but some of the lines are confusing me. I hope you'll explain them to me. Here's the code with my comments:

#!/usr/sbin/perl
use File::Find;
our %old;

#find(subroutine, dir to search through)
find(\&getarchive,".");

#print dirs to archive
printold(each %old);

#automatically does a recusive search for
#dirs older than 30 days
sub getarchive{
      #if a file
    if( -f ){
            # Get the current path and assigns it to $path
        my $path=\%old;
            #uncomment the line below to search for files older than 30 days
        #my $old = -M > 30;
            #archive dirs with all content older than 1 minute
        my $old = -M > 1/(24*60);
            #Loops through (the current dir?)
        for( grep(length,split'/',$File::Find::dir)){
                  #Both of these lines: ??                  
            ++${$path->{$_}}{"."}[$old];
            $path=$path->{$_};
                  
                  #I get that $ is incremented, but what does the variable $ do?

                  #$path->{$_} : $path is stored in {$_}?

                  #{"."}[$old] : What is this? I guess that this is were a dir to archive
                  #is saved, but how can you store multiple values in a variable? Or is
                  #$old an array/list?
                  
                  #$path=$path->{$_}; : gets the next dir?
        }
    }
}

sub printold{
      #Get the $p (path) and $d (dir) from the argument. Again, are $p and $d a
      #list and not variables? Otherwise I don't see how you loop through them
    my($p,$d)=@_;
      # Can't figure this out
    for( keys %{$d} ){
            #Loop to next key unless the current key is a HASH? What is a HASH?            
        next unless ref($d->{$_}) eq "HASH";
            
            #d->{$_}{"."}[1] and d->{$_}{"."}[0] I don't understand
        if( $d->{$_}{"."}[1] ){
            if( $d->{$_}{"."}[0] ){
                printold("$p/$_",$d->{$_});
            }else{
                print "$p/$_\n";
            }
        }
    }
}

As you can see I'm all new to Perl so the syntax confuses me a great deal.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now