Home > Archive > PERL Beginners > March 2004 > Search for a file pattern in a directory tree recursively
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Search for a file pattern in a directory tree recursively
|
|
| Rajesh Dorairajan 2004-03-26, 11:14 pm |
| Hello All,
I went through all the documentation and previous mail posts about
File::Find and finally decided I needed some help.
I've a directory structure I need to parse. The directory contains
subdirectories with filenames such as
full094382.db
full483292.db
Now, I need to parse through each subdirectory and pick up the name of the
file that was MODIFIED MOST RECENTLY. I do have a sort of a code to start
with.
use strict;
use warnings;
$\ = "\n";
use File::Find;
my $localdir = 'C:/docs';
my @files;
find(
sub { push ( @fullcrls, $File::Find::name ) if /^(full)\w*(\.db)$/ },
$localdir );
foreach ( @fullcrls ) {
print;
}
However, I am not able to figure how to filter out the repeat entries in a
sub-directory such as
C:/docs/dir1/full094382.db
C:/docs/dir1/full483292.db
C:/docs/dir2/full482952.db
C:/docs/dir2/full930284.db
..
..
..
In the above example, I need only need filename from dir1 and dir2 that was
last modified. Is there a way to do this filtration in the find( sub {} )
above?
Any help will be deeply appreciated.
Thanks,
Rajesh Dorairajan
rajesh.dorairajan@tumbleweed.com
| |
| John W. Krahn 2004-03-26, 11:15 pm |
| Rajesh Dorairajan wrote:
>
> Hello All,
Hello,
> I went through all the documentation and previous mail posts about
> File::Find and finally decided I needed some help.
>
> I've a directory structure I need to parse. The directory contains
> subdirectories with filenames such as
>
> full094382.db
> full483292.db
>
> Now, I need to parse through each subdirectory and pick up the name of the
> file that was MODIFIED MOST RECENTLY. I do have a sort of a code to start
> with.
>
> use strict;
> use warnings;
>
> $\ = "\n";
>
> use File::Find;
>
> my $localdir = 'C:/docs';
> my @files;
>
> find(
> sub { push ( @fullcrls, $File::Find::name ) if /^(full)\w*(\.db)$/ },
> $localdir );
>
> foreach ( @fullcrls ) {
> print;
> }
>
> However, I am not able to figure how to filter out the repeat entries in a
> sub-directory such as
>
> C:/docs/dir1/full094382.db
> C:/docs/dir1/full483292.db
> C:/docs/dir2/full482952.db
> C:/docs/dir2/full930284.db
>
> In the above example, I need only need filename from dir1 and dir2 that was
> last modified. Is there a way to do this filtration in the find( sub {} )
> above?
This should do what you want:
use strict;
use warnings;
use File::Find;
use vars qw( $dir $name );
*dir = *File::Find::dir;
*name = *File::Find::name;
my $localdir = 'C:/docs';
my %files;
find(
sub {
return unless -f;
( not exists $files{ $dir } or $files{ $dir }{ mtime } > -M _ )
and ( @{ $files{ $dir } }{ qw/name mtime/ } = ( $name, -M _ ) )
}, $localdir
);
for my $entry ( values %files ) {
print $entry->{ name }, "\n";
}
__END__
John
--
use Perl;
program
fulfillment
| |
| Rajesh Dorairajan 2004-03-29, 3:33 pm |
| John,
Thanks for the script. I need to filter the result by a specific file
extension, how do I that? I tried,
( not exists $files{ $dir } or $files{ $dir }{ mtime } > -M _ )
and ( @{ $files{ $dir } }{ qw/name mtime/ } = ( $name, -M _ ) )
and ( /^(full)\w*(\.db)$/ )
It does not seem to work. Actually I would be grateful if you could also
help me understand how the script works. I cannot figure out the what role _
plays. I know -M is "Script start time minus file modification time, in
days".
Thanks
Rajesh
> -----Original Message-----
> From: John W. Krahn [mailto:krahnj@acm.org]
> Sent: Friday, March 26, 2004 1:24 AM
> To: beginners@perl.org
> Subject: Re: Search for a file pattern in a directory tree recursively
>
>
> Rajesh Dorairajan wrote:
>
> Hello,
>
> the name of the
> code to start
> /^(full)\w*(\.db)$/ },
> repeat entries in a
> and dir2 that was
> find( sub {} )
>
> This should do what you want:
>
> use strict;
> use warnings;
> use File::Find;
> use vars qw( $dir $name );
> *dir = *File::Find::dir;
> *name = *File::Find::name;
>
> my $localdir = 'C:/docs';
> my %files;
>
> find(
> sub {
> return unless -f;
> ( not exists $files{ $dir } or $files{ $dir }{ mtime } > -M _ )
> and ( @{ $files{ $dir } }{ qw/name mtime/ } = ( $name, -M _ ) )
> }, $localdir
> );
>
> for my $entry ( values %files ) {
> print $entry->{ name }, "\n";
> }
>
> __END__
>
>
>
> John
> --
> use Perl;
> program
> fulfillment
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>
| |
| John W. Krahn 2004-03-29, 6:42 pm |
| Rajesh Dorairajan wrote:
>
> From: John W. Krahn [mailto:krahnj@acm.org]
>
> Thanks for the script. I need to filter the result by a specific file
> extension, how do I that? I tried,
>
> ( not exists $files{ $dir } or $files{ $dir }{ mtime } > -M _ )
> and ( @{ $files{ $dir } }{ qw/name mtime/ } = ( $name, -M _ ) )
> and ( /^(full)\w*(\.db)$/ )
Just substitute:
return unless -f;
With:
return unless /^full\w*\.db$/;
> It does not seem to work. Actually I would be grateful if you could also
> help me understand how the script works. I cannot figure out the what role _
> plays. I know -M is "Script start time minus file modification time, in
> days".
_ is a special file handle that works with the file test operators.
perldoc -f -X
[snip]
If any of the file tests (or either the `stat' or
`lstat' operators) are given the special
filehandle consisting of a solitary underline,
then the stat structure of the previous file test
(or stat operator) is used, saving a system call.
(This doesn't work with `-t', and you need to
remember that lstat() and `-l' will leave values
in the stat structure for the symbolic link, not
the real file.) Example:
print "Can do.\n" if -r $a || -w _ || -x _;
stat($filename);
print "Readable\n" if -r _;
print "Writable\n" if -w _;
print "Executable\n" if -x _;
print "Setuid\n" if -u _;
print "Setgid\n" if -g _;
print "Sticky\n" if -k _;
print "Text\n" if -T _;
print "Binary\n" if -B _;
John
--
use Perl;
program
fulfillment
|
|
|
|
|