Of all the searches I've done on the subject, everyone has asked essentailly the basic, "how do I move/copy/read/search" a directory tree? And, as we all know, File::Find is the tool of choice.

The problem is, this module only works on one tree descent at a time; trying to instantiate two copies of the code causes incorrect results. So, this renders the following problem a tad more complicated.

The scenario is this: I have various external disks; some are a working (live) disks that may contain about 50-200G worth of high-res images. then, there's the larger, 1-terrabyte disk (raid) that has directories that mirror the "live" working disks. Essentially, it's a recovery disk that I bring out once in a while to do back-ups. For reasons beyond the scope of this discussion, it has a series of standard directory trees, each of which represents the working disks.

What I need to do is run a perl script (which will later be embedded in a much larger perl app) that updates the back-up directory tree with the changes made on the live disk. I "could" do a simplistic "cp -r" type thing and just force-write everything over, but only sporadic files are updated, and usually not that often. It'd be an overkill to do such work, for reasons that I hope don't need to be clarified.

What I want to do is something similar to what "tar" can do: just update files that have been modified (including adding new files), leaving everything else alone. But the disk is not a tar archive. I could use cygwin shell's "find" like in unix to find files that have been updated since a certain time, and just copy those files, but the need to actually check the destination disk's timestamp on the correllating file for absolute verification (including checking size) is necessary.

I wrote a find function that uses File::Find, but as noted, it can't descend two trees at the same time, and I can't instantiate two copies. So, what more is there I can do? I wrote the following program, called "duofind", which descends srcdir and reports only files that also exist in destdir (I haven't done the lstat() tests to see if the file needs updating yet) because I need to solve the more important problem: it does NOT report files that DO NOT exist in destdir, nor does it report files in destdir that do not exist in srcdir.

Here's what I have so far:

#!/usr/bin/perl -w =head1 Command: duofind srcdir destdir Descends srcdir and reports only files that also exist in destdir. It does NOT report files that DO NOT exist in destdir, nor does it report files in destdir that do not exist in srcdir. =cut use File::Find; use Cwd; sub cmp { return if -d; $file2 = $_; if ($file1 eq $file2) { print "### Found in $File::Find::dir/$_\n" + } } sub doit { my $f = shift; opendir DIR, $f || die "can't open $f"; foreach my $file (readdir DIR) { next if ($file eq "." || $file eq ".."); if (-d "$f/$file") { doit("$f/$file"); next } $file1 = $file; $src = $f; print "Looking for $src/$file1\n"; find({ wanted => \&cmp }, $dest); } close DIR; } die "need a src dir" if (!($src = shift)); die "need a dest dir" if (!($dest = shift)); die "src cannot equal dest" if ($src eq $dest); doit ($src);

Pardon the sloppy coding style.. this is just a temporary codeset for testing purposes. dan

2004-11-27 Edited by Arunbear: Changed title from 'searching and <i>modifying</i> two directory trees'; HTML in node titles is not supported


In reply to searching and modifying two directory trees by argv

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.