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

I am looking for all *.htm files in a directory tree using File::Find and building up an array with all files found.

Then for each file in the array I want to find the file with the same name in a target directory tree and process the files as I find them.

Iam using the following but it is not working. Where am I going wrong?.

use File::Find; my @directory = ("src"); my @sourcefiles; find(\&sourcefind, @directory); sub sourcefind { open(FL, $File::Find::name); push @sourcefiles, $File::Find::name if -f and /\.htm*/ ; close(FL); } foreach $srcfile (@sourcefiles) { find(\&targetfind, 'D:\Projects\perl\targ'); } sub targetfind { open(FL, $File::Find::name); # process the target file print $_." target found\n" if -f and /$srcfile/; close(FL); }

Replies are listed 'Best First'.
Re: Finding files in a directory tree from and array of file names
by Zaxo (Archbishop) on Oct 15, 2001 at 16:11 UTC

    In addition to pixel's and tommyw's remarks, there is this. In targetfind() you may have trouble from regex metacharacters in $srcfile, particularly in using windows style paths. This will correct the problem:

    print "$_ target found\n" if -f and /\Q$srcfile\E/;
    I'd be inclined to make the sub targetfind{} anonymous within the find call to prevent its use outside the lexical scope of $srcfile.

    After Compline,
    Zaxo

Re: Finding files in a directory tree from and array of file names
by Anonymous Monk on Oct 15, 2001 at 17:04 UTC
    Thanks everyone for your help. Making targetfind anonymous within find was the key.
    My code is now:
    use File::Find; use strict; my @directory = ("\src"); my @sourcefiles; my $srcfile; find(\&sourcefind, @directory); sub sourcefind { open(FL, $File::Find::name); push @sourcefiles, $_ if -f and /\.htm*/ ; close(FL); } foreach $srcfile (@sourcefiles) { find( sub {print "$_ target found\n" if -f and /\Q$srcfile\E/;}, 'D:\Projects\perl\targ'); }

      As long as you've got unique filenames across all your dictories...

      Since you're no longer storing the path name, subdir1/file.htm and subdir2/file.htm will both be stored simply as file.htm. When you find a file called file.htm below the target directory, it will appear to match both of these.

      This isn't necessarilly a problem, as long as you're aware of the possibility.

Re: Finding files in a directory tree from and array of file names
by tommyw (Hermit) on Oct 15, 2001 at 15:52 UTC

    The files found initially will be relative to, and include, the searchpath itself. So you'll have (src\file1.html, src\subdir\file2.htm) etc. You then look for these filenames below a target directory. But do you need to strip off the src prefix first, or do you really have D:\Projects\perl\targ\src\file1.html?

    Update: I've just looked up the documentation on File::Find (better late than never), and of course, it appears that targetfind is trying to find the fully qualified filename within the unqualified filename. It's even less suprising that it fails (unless you've got really strange filenames in the target directory).

Re: Finding files in a directory tree from and array of file names
by pixel (Scribe) on Oct 15, 2001 at 15:19 UTC

    Can you tell us what you mean by "not working"? What behaviour were you expecting that you're not seeing?

    You may find more clues to what is actually going on if you used -w and use strict in your script.

    Blessed Be
    The Pixel

      By "not working" I mean that nothing is being displayed by the print command.
      Using use strict I get the following errors...
      Global symbol "$srcfile" requires explicit package name at D:\Projects +\perl\recurse.pl line 26. Global symbol "$srcfile" requires explicit package name at D:\Projects +\perl\recurse.pl line 34. Execution of D:\Projects\perl\recurse.pl aborted due to compilation er +rors.
      What exactly does this mean?

        Your @sourcefiles array contains $File::Find::name for each of the found files. This is the full pathname of the file.

        Later you check these values against the filename in $_. This only contains thea actual name of the file so your match will never work.

        strict turns on a number of constraints that will make your Perl scripts better. One of the most useful is that it forces you to think about variable scoping and predeclare variables. This is most often done using my. That's the error that you're seeing.

        I didn't really expect you to just add the line without reading the documentation first :-)

        Blessed Be
        The Pixel

Re: Finding files in a directory tree from and array of file names
by George_Sherston (Vicar) on Oct 15, 2001 at 14:45 UTC
    Do you need a leading "/" or "\" before "src" in my @directory?

    Also I think the opens may be redundant as you only seem to be processing the names of the files, not their contents - though perhaps this not so in the finished code.

    § George Sherston
      No, the leading \ isn't the problem.
      And yes, the open is redundant here but as you say this isn't the complete code.

      I think the problem is either in the sub targetfind function or the foreach