Solved

Report old files

Posted on 2004-08-24
6
157 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
read PayflowPro reports using the report metadata using perl 11 43
Perl output collect 7 67
stftime format 4 56
Using Perl to parse rows 7 97
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
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…

820 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