Home > Archive > PERL Beginners > July 2005 > File::Find if match rename
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
File::Find if match rename
|
|
| Brian Volk 2005-07-24, 8:29 pm |
| Hi all,
file_1( item_nums ) file_2 ( mfg_nums )
70624.pdf 00020.pdf
70280.pdf 00020.pdf
70387.pdf 00020.pdf
70207.pdf 00035.pdf
30317.pdf 00035.pdf
70777.pdf 00040.pdf
70332.pdf 00067.pdf
70445.pdf 00067.pdf
I have two text files and I have a directory of .pdf files that are named
00020.pdf 00035.pdf 00040.pdf 00067.pdf. ( same as records in file_2 ) What
I need to do is look at each record in file_2 and see if the .pdf file
exist.. if so copy that file to a new directory and rename it to the
corresponding record in file one for example; the first value 00020 would
be renamed ( if file exits ) to 70624.pdf and the second value 00020 would
be renamed 70280.pdf ...Which would actually be the same .pdf file just w/ a
different name... Below is what I have so far... I not getting any errors
but nothing is happening.? Any hints or suggestions would be greatly
appreciated. I was also thinking a hash may be better since I have unique
records in file 1... not sure...
#!/usr/bin/perl -w
use strict;
use File::Find;
my $item_nums = 'c:/brian/spartan/hp_items.txt' ;
my $mfg_nums ='c:/brian/spartan/mfg_num.txt' ;
open(ITEM_NUMS, "<", $item_nums) or die "couldn't read item_nums: $!";
open(MFG_NUMS, "<", $mfg_nums) or die "couldn't read mfg_nums: $!";
my @item_nums = <ITEM_NUMS> ;
my @mfg_nums = <MFG_NUMS>;
close(ITEM_NUMS);
close(MFG_NUMS);
find(\&wanted, 'c:/Spartan/MSDS/number');
sub wanted {
while (@mfg_nums) {
my $mfg_num = shift(@mfg_nums);
chomp $mfg_num;
my $new_pdf = shift(@item_nums);
chomp $new_pdf;
if ( m/$mfg_num/ ) {
rename "$_", "c:/brian/spartan/$new_pdf"
}
}
}
Thanks!
Brian Volk
HP Products
317.298.9950 x1245
<mailto:bvolk@hpproducts.com> bvolk@hpproducts.com
| |
| Xavier Noria 2005-07-24, 8:29 pm |
| On Jul 22, 2005, at 17:16, Brian Volk wrote:
> #!/usr/bin/perl -w
>
> use strict;
> use File::Find;
>
> my $item_nums = 'c:/brian/spartan/hp_items.txt' ;
> my $mfg_nums ='c:/brian/spartan/mfg_num.txt' ;
>
> open(ITEM_NUMS, "<", $item_nums) or die "couldn't read item_nums: $!";
> open(MFG_NUMS, "<", $mfg_nums) or die "couldn't read mfg_nums: $!";
>
> my @item_nums = <ITEM_NUMS> ;
> my @mfg_nums = <MFG_NUMS>;
>
> close(ITEM_NUMS);
> close(MFG_NUMS);
>
> find(\&wanted, 'c:/Spartan/MSDS/number');
>
> sub wanted {
>
> while (@mfg_nums) {
> my $mfg_num = shift(@mfg_nums);
> chomp $mfg_num;
> my $new_pdf = shift(@item_nums);
> chomp $new_pdf;
>
> if ( m/$mfg_num/ ) {
> rename "$_", "c:/brian/spartan/$new_pdf"
> }
> }
> }
Looks like the logic is wrong, since in the first call to wanted()
the while lookp exhausts @mfg_nums.
I would take another apporach (untested and simple, but you see the
idea):
chomp @item_nums;
chomp @mfg_nums;
chdir 'c:/Spartan/MSDS/number' or die $!;
my %existing_pdfs = map { $_ => 1 } glob "*.pdf"; # assumes a
flat dir
for (my $i = 0; $i < @mfg_nums; ++$i) { # this is the
real fix
my $pdf = $mfg_nums[$i];
rename $_, "c:/brian/spartan/$item_nums[$i]" if
$existing_pdfs{$pdf};
}
Note that the set of PDFs under number can be modified while we are
in the for loop, thus invalidating %existing_pdfs as a representative
of that set. This may or may not be an issue. If you wanted that to
be really transactional some additional code would be needed.
-- fxn
| |
| Jeff 'japhy' Pinyan 2005-07-24, 8:29 pm |
| On Jul 22, Brian Volk said:
> I have two text files and I have a directory of .pdf files that are named
> 00020.pdf 00035.pdf 00040.pdf 00067.pdf. ( same as records in file_2 ) What
> I need to do is look at each record in file_2 and see if the .pdf file
> exist.. if so copy that file to a new directory and rename it to the
> corresponding record in file one for example; the first value 00020 would
> be renamed ( if file exits ) to 70624.pdf and the second value 00020 would
> be renamed 70280.pdf ...Which would actually be the same .pdf file just w/ a
If the PDF files are in a given directory (and not hidden in various
locations further down that directory's subdirectories) then you won't
need File::Find. I would also be a little wary of renaming files as
File::Find was operating. I personally don't know if that would have an
effect, but I would stay clear of it myself.
As for your data structures, you *could* create a hash, but I don't think
there's necessarily a need for it. Have two parallel arrays isn't so bad
in this case. However, the way I see it, you don't need arrays at all.
Here's how I would solve the problem:
#!/usr/bin/perl
use strict; # I was very happy to see
use warnings; # you had these in your code
my $item_file = "c:/brian/spartan/hp_items.txt";
my $mfg_file = "c:/brian/spartan/mfg_num.txt";
my $src_dir = "c:/spartan/msds/number"; # source directory
my $dst_dir = "c:/brian/spartan"; # destination directory
open ITEM, "< $item_file" or die "can't read $item_file: $!";
open MFG, "< $mfg_file" or die "can't read $mfg_file: $!";
while (my $old = <MFG> ) {
my $new = <ITEM>;
chomp($old, $new);
if (-e "$src_dir/$old") {
rename "$src_dir/$old" => "$dst_dir/$new"
or warn "can't rename $src_dir/$old to $dst_dir/$new: $!";
}
}
--
Jeff "japhy" Pinyan % How can we ever be the sold short or
RPI Acacia Brother #734 % the cheated, we who for every service
http://japhy.perlmonk.org/ % have long ago been overpaid?
http://www.perlmonks.org/ % -- Meister Eckhart
| |
| Brian Volk 2005-07-24, 8:29 pm |
|
> -----Original Message-----
> From: Jeff 'japhy' Pinyan [mailto:japhy@perlmonk.org]
> Sent: Friday, July 22, 2005 11:44 AM
> To: Brian Volk
> Cc: Beginners (E-mail)
> Subject: Re: File::Find if match rename
>
>
> On Jul 22, Brian Volk said:
>
> that are named
> in file_2 ) What
> the .pdf file
> it to the
> value 00020 would
> value 00020 would
> .pdf file just w/ a
>
> If the PDF files are in a given directory (and not hidden in various
> locations further down that directory's subdirectories) then
> you won't
> need File::Find. I would also be a little wary of renaming files as
> File::Find was operating. I personally don't know if that
> would have an
> effect, but I would stay clear of it myself.
>
> As for your data structures, you *could* create a hash, but I
> don't think
> there's necessarily a need for it. Have two parallel arrays
> isn't so bad
> in this case. However, the way I see it, you don't need
> arrays at all.
>
> Here's how I would solve the problem:
>
> #!/usr/bin/perl
>
> use strict; # I was very happy to see
> use warnings; # you had these in your code
>
> my $item_file = "c:/brian/spartan/hp_items.txt";
> my $mfg_file = "c:/brian/spartan/mfg_num.txt";
> my $src_dir = "c:/spartan/msds/number"; # source directory
> my $dst_dir = "c:/brian/spartan"; # destination directory
>
> open ITEM, "< $item_file" or die "can't read $item_file: $!";
> open MFG, "< $mfg_file" or die "can't read $mfg_file: $!";
>
> while (my $old = <MFG> ) {
> my $new = <ITEM>;
> chomp($old, $new);
>
> if (-e "$src_dir/$old") {
> rename "$src_dir/$old" => "$dst_dir/$new"
> or warn "can't rename $src_dir/$old to $dst_dir/$new: $!";
> }
> }
>
> --
> Jeff "japhy" Pinyan % How can we ever be the sold short or
> RPI Acacia Brother #734 % the cheated, we who for every service
> http://japhy.perlmonk.org/ % have long ago been overpaid?
> http://www.perlmonks.org/ % -- Meister Eckhart
Wow! Thank you very much! It is spelled out plain as day on page 89 of
Learning Perl, ugh! :~)
---- Chapter 6 I/O Basics, Input from the Diamond Operator -----
while (defined($line = <> )) {
chomp(line);
print "It was $line that I saw!\n";
}
So, if we run this program w/ the invocation arguments fred, it will say
something like: "It was [a line from file fred] that I saw!", "It was
[another line from fred] that I saw!" on and on until it reaches the end of
the file.
---- End of Quote ---
Thanks again it worked great!
Brian Volk
|
|
|
|
|