File::Find and tree copying

A

Anonymous

As usually, my apologies for the newbie type question from an infrequent
user.

I have a directory tree (path is $tree0), and I would like to duplicate the
tree structure into two other tree roots ($tree1 and $tree2). I want to
process the files in the original tree with two different subroutines, call
them Process1 and Process2 so that the files in the duplicated trees are not
really exact copies but versions produces by Process1(individualFile) and
Process2(individualFile).

I can find my way down the original tree OK using File::Find, get the name
($File::Find::name) (.... this is progress for a novice, so don't laugh) and
do something with the file. But duplicating the structure has me completely
baffled.

#!/bin/perl
use File::Find;
my $tree0="c:\\k\\origtree";

# Find the original files
find(\&processAllFiles, $tree0);

# Subroutine that decends the tree.
sub processAllFiles{
print "$File::Find::name\n";

# HELP HELP
}


I would appreciate any help, whether general pointer to a place to read, an
appropriate old note in the archive, or code snippet.

Cheers,
 
A

Anno Siegel

Anonymous said:
As usually, my apologies for the newbie type question from an infrequent
user.

I have a directory tree (path is $tree0), and I would like to duplicate the
tree structure into two other tree roots ($tree1 and $tree2). I want to
process the files in the original tree with two different subroutines, call
them Process1 and Process2 so that the files in the duplicated trees are not
really exact copies but versions produces by Process1(individualFile) and
Process2(individualFile).

Calling the operations Process1 and Process2 adds nothing to help us
understand your problem. What do Process1 and Process2 expect as an
argument (individualFile)? An open filehandle? A file name? File content
as a single multiline string? A list of strings? And how do they deliver
the modified file? As a string? A list of lines? Does it write it to
disk somewhere? Without that information, "Process1(individualFile)" is
nothing but claptrap (and not even Perl claptrap at that).

I'll assume that Process1() has two arguments, one the name of the
original file and the other the name of the new file to write, so a
call would look like

Process1( $original, $new);
I can find my way down the original tree OK using File::Find, get the name
($File::Find::name) (.... this is progress for a novice, so don't laugh) and
do something with the file. But duplicating the structure has me completely
baffled.

#!/bin/perl

No strict, no warnings!
use File::Find;
my $tree0="c:\\k\\origtree";

# Find the original files
find(\&processAllFiles, $tree0);

# Subroutine that decends the tree.
sub processAllFiles{
print "$File::Find::name\n";

# HELP HELP
}

I'll pretend you have only one target tree $root1 and only one file-
modifying process.

You'll have to do different things depending on whether the file in
$File::Find::name is a directory or a normal file. If it is a directory,
crate the "parallel" directory in $tree1. If it is a file, the target
directory will already have been created, just call Process1 with the
original and new names.

For both actions you'll want to change (the initial) part of a path
name to something else. This applies to directories as well as files,
so it's a candidate for a subroutine. Untested:

#!/usr/bin/perl
use strict; use warnings;
use File::Find;
use Errno qw( EEXIST); # perldoc Errno for more

my $tree0 = '...'; # substitute your...
my $tree1 = '...'; # ...actual locations

find sub {
if ( -d ) {
my $dir = change_path( $File::Find::Name, $tree0, $tree1);
mkdir $dir or $!{ EEXIST} or die "Can't create directory $dir: $!";
} else {
my $out = change_path( $File::Find::Name, $tree0, $tree1);
Process1( $File::Find::name, $out);
}
}, $tree0;

sub change_path {
my ( $path, $old_prefix, $new_prefix) = @_;
die "'$path' doesn't begin with '$old_prefix'" if
index( $path, $old_path) != 0;
substr( $path, 0, length $old_prefix) = $new_prefix;
$path;
}

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top