Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Rename files using directory names (http://www.velocityreviews.com/forums/t905372-rename-files-using-directory-names.html)

Peter Jamieson 11-15-2007 01:33 PM

Rename files using directory names
 
I have inherited many .rtf files contained in a directory structure like:
patient_data/patient1/2007_07_11/test1.rtf
where there are many patient directories such as patient1, patient2 etc
and many date directories such as 2007_07_11, 2007_07_09 etc
and there may be many .rtf files per patient and date combination.

What I would like to do is create new unique names for each .rtf file
based on the directory names: eg patient1_2007_07_11.test1.rtf
and put them into a new directory named patient_files.

I have checked out File::Find and tested the following script.
It lists all the files OK as expected like test1.rtf, test2.rtf etc
It merely replaces "_" with " " just as a test script.

However I cannot figure out how to do a rename for what
I would like the new file names to be namely in the
form of: patient1_2007_07_11.test1.rtf

Any help appreciated!, Cheers Peter

#!/usr/bin/perl
use warnings;
use strict;
use File::Find;

my $dir = '/patient_data/patient';

find(\&underscores, $dir);

sub underscores {
next if -d $_;
next if /^\./;
next unless /_/;
my $new_name = $_;
$new_name =~ s/_/ /g; # just for testing!
chdir($File::Find::dir);
rename($_, $new_name) or die $!;
print "$new_name \n";
}



John W. Krahn 11-15-2007 06:53 PM

Re: Rename files using directory names
 
Peter Jamieson wrote:
>
> I have inherited many .rtf files contained in a directory structure like:
> patient_data/patient1/2007_07_11/test1.rtf
> where there are many patient directories such as patient1, patient2 etc
> and many date directories such as 2007_07_11, 2007_07_09 etc
> and there may be many .rtf files per patient and date combination.
>
> What I would like to do is create new unique names for each .rtf file
> based on the directory names: eg patient1_2007_07_11.test1.rtf
> and put them into a new directory named patient_files.
>
> I have checked out File::Find and tested the following script.
> It lists all the files OK as expected like test1.rtf, test2.rtf etc
> It merely replaces "_" with " " just as a test script.
>
> However I cannot figure out how to do a rename for what
> I would like the new file names to be namely in the
> form of: patient1_2007_07_11.test1.rtf
>
> Any help appreciated!, Cheers Peter
>
> #!/usr/bin/perl
> use warnings;
> use strict;
> use File::Find;
>
> my $dir = '/patient_data/patient';
>
> find(\&underscores, $dir);
>
> sub underscores {
> next if -d $_;
> next if /^\./;
> next unless /_/;


You shouldn't use next from within a subroutine you should use return
instead. According to your example above your file names do not contain
a '_' character?


> my $new_name = $_;
> $new_name =~ s/_/ /g; # just for testing!
> chdir($File::Find::dir);


By default File::Find::find() already has you in the $File::Find::dir
directory so this is superfluous. You should always verify that system
functions like chdir() have worked, but it doesn't matter if it failed
as you are already in the $File::Find::dir directory!


> rename($_, $new_name) or die $!;


You are trying to move the current file to the same directory. You
probably want to include the new path name in the target:
"patient_files/$new_name" but you probably want to use an absolute path
instead of a relative path.


> print "$new_name \n";
> }



John
--
use Perl;
program
fulfillment

Peter Jamieson 11-15-2007 09:22 PM

Re: Rename files using directory names
 

"John W. Krahn" <krahnj@telus.net> wrote in message
news:473C959D.2992BC4C@telus.net...
> Peter Jamieson wrote:
>>
>> I have inherited many .rtf files contained in a directory structure like:
>> patient_data/patient1/2007_07_11/test1.rtf
>> where there are many patient directories such as patient1, patient2 etc
>> and many date directories such as 2007_07_11, 2007_07_09 etc
>> and there may be many .rtf files per patient and date combination.
>>
>> What I would like to do is create new unique names for each .rtf file
>> based on the directory names: eg patient1_2007_07_11.test1.rtf
>> and put them into a new directory named patient_files.
>>
>> I have checked out File::Find and tested the following script.
>> It lists all the files OK as expected like test1.rtf, test2.rtf etc
>> It merely replaces "_" with " " just as a test script.
>>
>> However I cannot figure out how to do a rename for what
>> I would like the new file names to be namely in the
>> form of: patient1_2007_07_11.test1.rtf
>>
>> Any help appreciated!, Cheers Peter
>>
>> #!/usr/bin/perl
>> use warnings;
>> use strict;
>> use File::Find;
>>
>> my $dir = '/patient_data/patient';
>>
>> find(\&underscores, $dir);
>>
>> sub underscores {
>> next if -d $_;
>> next if /^\./;
>> next unless /_/;

>
> You shouldn't use next from within a subroutine you should use return
> instead. According to your example above your file names do not contain
> a '_' character?
>
>
>> my $new_name = $_;
>> $new_name =~ s/_/ /g; # just for testing!
>> chdir($File::Find::dir);

>
> By default File::Find::find() already has you in the $File::Find::dir
> directory so this is superfluous. You should always verify that system
> functions like chdir() have worked, but it doesn't matter if it failed
> as you are already in the $File::Find::dir directory!
>
>
>> rename($_, $new_name) or die $!;

>
> You are trying to move the current file to the same directory. You
> probably want to include the new path name in the target:
> "patient_files/$new_name" but you probably want to use an absolute path
> instead of a relative path.
>
>
>> print "$new_name \n";
>> }

>
>
> John
> --
> use Perl;
> program
> fulfillment


Thanks John!....your comments have been most useful.
I will need to look at the use of "next" and "return" in
more detail....cheers, Peter



Peter Jamieson 11-15-2007 09:22 PM

Re: Rename files using directory names
 

"Jim Gibson" <jimsgibson@gmail.com> wrote in message
news:151120071143050921%jimsgibson@gmail.com...
> In article <NUX_i.13265$CN4.10200@news-server.bigpond.net.au>, Peter
> Jamieson <ldolan@thinkinghatbigpond.net.au> wrote:
>
>> I have inherited many .rtf files contained in a directory structure like:
>> patient_data/patient1/2007_07_11/test1.rtf
>> where there are many patient directories such as patient1, patient2 etc
>> and many date directories such as 2007_07_11, 2007_07_09 etc
>> and there may be many .rtf files per patient and date combination.
>>
>> What I would like to do is create new unique names for each .rtf file
>> based on the directory names: eg patient1_2007_07_11.test1.rtf
>> and put them into a new directory named patient_files.
>>
>> I have checked out File::Find and tested the following script.
>> It lists all the files OK as expected like test1.rtf, test2.rtf etc
>> It merely replaces "_" with " " just as a test script.
>>
>> However I cannot figure out how to do a rename for what
>> I would like the new file names to be namely in the
>> form of: patient1_2007_07_11.test1.rtf
>>
>> Any help appreciated!, Cheers Peter
>>
>> #!/usr/bin/perl
>> use warnings;
>> use strict;
>> use File::Find;
>>
>> my $dir = '/patient_data/patient';
>>
>> find(\&underscores, $dir);
>>
>> sub underscores {
>> next if -d $_;
>> next if /^\./;
>> next unless /_/;

>
> Those should be 'return' statements, as you are not in an explicit loop.
>
>> my $new_name = $_;
>> $new_name =~ s/_/ /g; # just for testing!
>> chdir($File::Find::dir);

>
> There is no need to chdir here, as find will do it for you as long as
> you have not set the nochdir option.
>
>> rename($_, $new_name) or die $!;
>> print "$new_name \n";
>> }

>
> You need to 1) get the full path name, 2) strip off the leading
> directory, 3) change all of the path separators to underscores, 4) add
> the new directory name at the front. Something like:
>
> #!/usr/local/bin/perl
> use warnings;
> use strict;
> use File::Find;
>
> my $dir = '/patient_data';
> my $newdir = '/patient_files';
>
> find(\&moveit, $dir);
>
> sub moveit {
> return if -d $_;
> return if /^\./;
> my $new_name = $File::Find::name;
> $new_name =~ s{^$dir/}{};
> $new_name =~ s{/}{_}g;
> $new_name = "$newdir/$new_name";
> rename($File::Find::name,$new_name);
> }
>
> You might want to check if $new_name already exists.
>
> --
> Jim Gibson
>


Hi Jim,
Thank you for your comments and suggestions!
I will rewrite some code based on the example you gave.
Your comment to check if a file name may already exist
is apt as by manual inspection I have noticed many
apparently duplicate files.
John Krahn has also mentioned my faulty use of "next" and "return"
so I need to correct my understanding of the difference.
Your help is greatly appreciated!...cheers, Peter.



John W. Krahn 11-16-2007 02:25 AM

Re: Rename files using directory names
 
Peter Jamieson wrote:
>
> "John W. Krahn" <krahnj@telus.net> wrote in message
> news:473C959D.2992BC4C@telus.net...
> >
> > John
> > --
> > use Perl;
> > program
> > fulfillment


Please don't quote sigs. TIA


> Thanks John!....your comments have been most useful.
> I will need to look at the use of "next" and "return" in
> more detail....cheers, Peter


next (and last and redo) are loop (for, foreach, while, until and {})
control keywords.

perldoc perlsyn (specifically the "Loop Control" section.)


return is a keyword specifically for the purpose of returning from
subroutines.

perldoc perlsub




John
--
use Perl;
program
fulfillment


All times are GMT. The time now is 08:09 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.