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

This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re: File::Find Questions
by Fletch (Bishop) on Dec 07, 2006 at 19:18 UTC
    ... i dont want to waste time, when i have peoples to suggest new good things ...

    Ahh, the wonderful attitude that pervades SoPW these days. "Why should I bother exerting any effort towards solving this trivial problem when I can get some sucker to do it for me?"

    That aside, your problem statement is still vague. Do you want the first file that happens to be returned (remember readdir doesn't guarantee any ordering of directory contets); or the first lexicographically of all matching files in a directory? In either case it's trivial to do (hint: keep a HoA keyed off $File::Find::dir).

      remember readdir doesn't guarantee any ordering of directory contets

      Indeed that's why when (lexicographic) order does matter for me with File::Find, I use

      preprocess => sub { reverse sort @_ },
Re: File::Find Questions
by liverpole (Monsignor) on Dec 07, 2006 at 19:27 UTC
    Hi kprasanna_79,

    I don't know how to do that with File::Find, which I seldom use, as I find the syntax a bit unwieldy.  But if you don't mind doing it with a simple subroutine, here's an example which'll work:

    use strict; use warnings; + my_find("/home/liverpole"); + sub my_find { my $dir = shift; opendir(FH, $dir) or die "Failed to open '$dir' ($!)\n"; my @files = readdir(FH); closedir FH; + my $show_n_files = 2; foreach (@files) { next if ($_ eq '.' or $_ eq '..'); my $path = "$dir/$_"; if (-f $path and $show_n_files) { print "$path\n"; --$show_n_files; } elsif (-d $path) { my_find($path); } } }

    Here, the variable $show_n_files can be set to the total number of files you wish to display from each directory.  You can use a -1 if you want to display all the files.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: File::Find Questions
by Util (Priest) on Dec 08, 2006 at 21:15 UTC

    Here are two solutions, one using File::Find, and a much shorter one using File::Find::Rule.

    Working, tested code:

    use File::Find; foreach my $path ( @project_paths ) { if ( my $xml_file = find_first_xml_file( $path ) ) { print "The first XML file under dir '$path' is '$xml_file'\n"; } else { print "No XML files found under dir '$path'\n"; } } sub find_first_xml_file { my ($dir) = @_; # Cannot take multiple dirs. my $file_found; my $wanted = sub { if ( $file_found ) { $File::Find::prune = 1; return; } if ( m{\.xml$}i ) { $file_found = $File::Find::name; $File::Find::prune = 1; } }; find( $wanted, $dir ); return $file_found; }

    use File::Find::Rule; foreach my $path ( @project_paths ) { my $rule = File::Find::Rule->file->name('*.xml')->start( $path ); if ( my $xml_file = $rule->match ) { print "The first XML file under dir '$path' is '$xml_file'\n"; } else { print "No XML files found under dir '$path'\n"; } }