Sorry to plop so much shabby code up here but I think I've stared at
this a little too long and am now incapable of catching my error.

This started out as just a helper script to help solve this problem:

Needing to cp files with number names from one directory to another.
Sometimes there might be some numbered files already in the target
directory.   So the problem was really two fold.

1)  Find the right files to copy by specific content.

    I'm doing this job with grep -rl, it seems to be the fastest by
    a hefty margin, to compile a list of the right files.

2) Once the list is compiled, copy the files over to a new directory
   making sure not to clobber possible exisiting files.

I'll probably try to turn the perl script into something more general 
that does the whole job eventually if this chore looks like it might
recur enough.

So (2) is all this script was meant to do at this point.

The script does the job and appears to run error free.  But after the
work is done I attempt to report 2 things.  The number of files copied
and the number of files now in the Target.

The second count is consistently wrong by a wide wide margin and I
am too blind to see why.

Here is a sample run (code encluded at the end) running the script 
the way it was intended to be used (script.pl TargetDir SourceList):

 ./cpNoClobber.pl test3 SourceList

  <16> Files copied to:
  /home/reader/News/agent/nntp/news.gmane.org/gmane/comp/lang/perl/test3

  <17> files now in:
  /home/reader/News/agent/nntp/news.gmane.org/gmane/comp/lang/perl/test3

Now lets look at the results of `ls' on the target:

  ls test3/[0-9]*|wc -l
  336

The script gets numbering right with no clobbers I think, but the reporting
is way wrong.

=====* Code *=====     =====* Code *=====     =====* Code *=====     

  ./cpNoClobber.pl

#!/usr/local/bin/perl -w

if(!$ARGV[1]){
   usage();
   print "Too few arguments.. exiting\n";
   exit;
}

if($ARGV[2]){
   usage();
   print "Too many arguments... exiting\n";
   exit;
}
use Cwd;
my $Cwd = getcwd;

use File::Copy;

my ($HiNum, $Copied, $TrgDir, @DirContent, $Cnt, $Line);
$TrgDir = shift;
$HiNum  = 0;
$Copied = 0;

opendir(DIR,$TrgDir) or die "can't opendir $TrgDir: $!";

## Find out if target directory has any numbered files in it.
## If it does get the highest number in there
@DirContent = grep { /^[0-9]/ } readdir(DIR);
if ($DirContent[0]){
   for(@DirContent){
     if($_ > $HiNum){
        $HiNum = $_;
     }
   } 
}      

## If we already have numbered files, Start our counter with
## the highest one
if($HiNum){
   $Cnt = $HiNum;
}

while(<>){
   chomp;
   $Cnt++ ;
   ## The first if clause here is unnecessary now... to be removed
   if($TrgDir){
      ## Add the correct path if our line doesn't start with '/'
     if(!/^\//){
         $Line = $Cwd ."/". $_;
      }
      if($TrgDir !~ /^\//){
         $TrgDir = $Cwd."/".$TrgDir;
      }
      ## Do what we came here for: copy the target files into target
      ## directory with fnames that won't clobber any existing filenames
      copy($Line,$TrgDir. "/". $Cnt) or die "can't copy $Line to <$TrgDir>: $!";
      $Copied++;
   }
}

## Report how many files were copied
print " <$Copied> Files copied to:\n $TrgDir\n\n";
print " ".CountTrgDir()."\n";
close(DIR);

sub CountTrgDir {
  my $DirCnt = 0;
  ## Recount the TargetDir
  @DirCnt = grep { /^[0-9]+/ } readdir(DIR); 

## Just in case there was something wrong with my technique using
## the array to get a count.. also tried the formulation commented out 
## below to see the actual count as it happened... still wrong
# @DirCnt = grep { /^[0-9]+/&& print "Counting <". $DirCnt++.">\n" } 
readdir(DIR); 
  return "<".(@DirCnt + 1)."> files now in:\n $TrgDir\n";
}

sub usage {
 print <<EOM;

Purpose: To copy files from a list on disk to the directory of choice.
         Numbering them with nonClobber names as we go (even if some
         numbered files are already in the directory).
Usage: \`$myscript TARGETDIRECTORY SOURCEFILE'
        (DIRECTORY= name of target directory)
NOTE: SOURCEFILE is likely to have been compiled like this:
      grep -rl 'REGEX'  SOMEDIRECTORY >SOURCEFILE (where SOMEDIRECTORY 
      is a directory full of email or posts.  We are looking to skim 
      off those with REGEX placing the filenames in SOURCEFILE, and
      copy them to another directory using \`$myscript ', so as to leave
      mail or news directory unharmed.

EOM
}  


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to