Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Report old files

Posted on 2004-08-24
6
Medium Priority
?
161 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 85

Accepted Solution

by:
ozo earned 2000 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 85

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

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…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
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…
Six Sigma Control Plans

972 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