Rename files using directory names

Discussion in 'Perl Misc' started by Peter Jamieson, Nov 15, 2007.

  1. 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";
    }
    Peter Jamieson, Nov 15, 2007
    #1
    1. Advertising

  2. 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
    John W. Krahn, Nov 15, 2007
    #2
    1. Advertising

  3. "John W. Krahn" <> wrote in message
    news:...
    > 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, Nov 15, 2007
    #3
  4. "Jim Gibson" <> wrote in message
    news:151120071143050921%...
    > In article <NUX_i.13265$>, 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.
    Peter Jamieson, Nov 15, 2007
    #4
  5. Peter Jamieson wrote:
    >
    > "John W. Krahn" <> wrote in message
    > news:...
    > >
    > > 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
    John W. Krahn, Nov 16, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?QmFzIEhlbmRyaWtz?=

    Directory and files names in temporary asp.net directory

    =?Utf-8?B?QmFzIEhlbmRyaWtz?=, Jan 28, 2005, in forum: ASP .Net
    Replies:
    5
    Views:
    823
    Juan T. Llibre
    Jan 31, 2005
  2. =?iso-8859-1?b?cultaQ==?=

    Rename multiple files using names in a text file

    =?iso-8859-1?b?cultaQ==?=, Sep 14, 2007, in forum: Python
    Replies:
    2
    Views:
    457
    =?iso-8859-1?b?cultaQ==?=
    Sep 15, 2007
  3. lucy
    Replies:
    6
    Views:
    148
    Michele Dondi
    Sep 3, 2004
  4. Tom Bates
    Replies:
    5
    Views:
    187
    Chris Mattern
    Apr 25, 2005
  5. iMath
    Replies:
    8
    Views:
    280
    emile
    Nov 13, 2012
Loading...

Share This Page