Rename files using directory names

Rename files using directory names

am 15.11.2007 14:33:33 von Peter Jamieson

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";
}

Re: Rename files using directory names

am 15.11.2007 19:53:51 von krahnj

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

Re: Rename files using directory names

am 15.11.2007 20:43:05 von Jim Gibson

In article , 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 /_/;

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

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Re: Rename files using directory names

am 15.11.2007 22:22:46 von Peter Jamieson

"John W. Krahn" 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

Re: Rename files using directory names

am 15.11.2007 22:22:46 von Peter Jamieson

"Jim Gibson" wrote in message
news:151120071143050921%jimsgibson@gmail.com...
> In article , 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 /_/;
>
> 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.

Re: Rename files using directory names

am 16.11.2007 03:25:53 von krahnj

Peter Jamieson wrote:
>
> "John W. Krahn" 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