Copying files and renaming them - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Copying files and renaming them

meshtebmeshteb Posts: 47Member
I've got a folder which is having subfolders,with each subfolder having files in it.Some of the files-names in these folders are identical,which will result in other files writing-over the others when copied in to the same(one) folder. What I want to do is to copy all the files in each subfolder into one folder and at the same time renaming them to avoid over-writing.Renaming can be done using unique way but incrementing by one e.g.


training1.wav
training2.wav
training3.wav
training4.wav
.
.
.
training234.wav

Any suggestions?

Comments

  • JonathanJonathan Posts: 2,914Member
    : I've got a folder which is having subfolders,with each subfolder having files in it.Some of the files-names in these folders are identical,which will result in other files writing-over the others when copied in to the same(one) folder. What I want to do is to copy all the files in each subfolder into one folder and at the same time renaming them to avoid over-writing.Renaming can be done using unique way but incrementing by one e.g.
    :
    :
    : training1.wav
    : training2.wav
    : training3.wav
    : training4.wav
    : .
    : .
    : .
    : training234.wav
    :
    : Any suggestions?
    :
    I suggest you have a hash:-

    my %names = ();

    Then go through each directory. For each file you find, do:-

    $names{$filename}++;

    That will keep track of a number for the file. Then insert the number like this:-

    $filename =~ s/(.w+)$/$names{$filename}$1/;

    Note that $filename here should either be the destination path and filename, or just the filename. It should not contain the source path, or this won't work.

    Hope this helps,

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • meshtebmeshteb Posts: 47Member
    Thanx for responding. I am bit confused with the explanation. Let me put this in practical terms.

    The folder which contains subfolders is in C drive, it is called Data. It has subfolders like Dr1,Dr2,...etc in it,with each subfolder containing files like service.wav,test1.wav,test2.wav,...etc.

    So I want to take all those files from all the subfolders and rename them in a unique way,and lastly put them in one folder (to avoid over-writting of files)( called Ouput in C drive also.In this format:

    training1.wav
    training2.wav
    training3.wav
    training4.wav
    .
    .
    .
    training234.wav

    May you please use these names in your code,if it is possible?


    : I've got a folder which is having subfolders,with each subfolder having files in it.Some of the files-names in these folders are identical,which will result in other files writing-over the others when copied in to the same(one) folder. What I want to do is to copy all the files in each subfolder into one folder and at the same time renaming them to avoid over-writing.Renaming can be done using unique way but incrementing by one e.g.
    : :
    : :
    : : training1.wav
    : : training2.wav
    : : training3.wav
    : : training4.wav
    : : .
    : : .
    : : .
    : : training234.wav
    : :
    : : Any suggestions?
    : :
    : I suggest you have a hash:-
    :
    : my %names = ();
    :
    : Then go through each directory. For each file you find, do:-
    :
    : $names{$filename}++;
    :
    : That will keep track of a number for the file. Then insert the number like this:-
    :
    : $filename =~ s/(.w+)$/$names{$filename}$1/;
    :
    : Note that $filename here should either be the destination path and filename, or just the filename. It should not contain the source path, or this won't work.
    :
    : Hope this helps,
    :
    : Jonathan
    :
    : ###
    : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    :
    :

  • JonathanJonathan Posts: 2,914Member
    : Thanx for responding. I am bit confused with the explanation. Let me
    : put this in practical terms.
    :
    : The folder which contains subfolders is in C drive, it is called
    : Data. It has subfolders like Dr1,Dr2,...etc in it,with each
    : subfolder containing files like service.wav,test1.wav,test2.wav,...etc.
    :
    : So I want to take all those files from all the subfolders and rename
    : them in a unique way,and lastly put them in one folder (to avoid
    : over-writting of files)( called Ouput in C drive also.In this format:
    :
    : training1.wav
    : training2.wav
    : training3.wav
    : training4.wav
    : .
    : .
    : .
    : training234.wav
    :
    : May you please use these names in your code,if it is possible?
    Ah-ha. Well, that would explain it - I thought you just wanted to add a number but retain the existing name, which was what I gave you code for.

    What do you need to know - just how to generated the filename? You just need to have a variable, like $filenum, that starts at 1. Then, when you copy the file, you generate it's name as "destination path raining$filenum.wav". Then to $filenum ++; to increment it.

    Or do you need to know how to do the copying itself?

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • meshtebmeshteb Posts: 47Member
    Yes,with pleasure!!
  • JonathanJonathan Posts: 2,914Member
    [b][red]This message was edited by Jonathan at 2004-1-18 15:25:1[/red][/b][hr]
    Hi,

    Sorry I took my time replying... Anyway, Perl doesn't have a built-in file copying mechanism - kinda strange, but anyway...we have to use the File::Copy module. Add this near the top of your script:-

    use File::Copy;

    Docs on this module can be found here:-
    http://search.cpan.org/~nwclark/perl-5.8.3/lib/File/Copy.pm

    The most important function is called copy:-

    copy $oldname, $newname;

    We then need to get a list of folders that contain the files.

    [code]my $startFolder = '/home/you/thefolder';
    opendir (DIR, $startFolder) || die "Can't access $startFolder";
    my @dirs = ();
    foreach (readdir(DIR)) {
    # Ignore "special" directories '.' and '..'.
    next if /^.+$/;

    # Do -d test to make sure it is a directory.
    -d && push @dirs, "$startFolder/$_";
    }
    closedir DIR;
    [/code]

    This gives us @dirs, which is the list of directories that may contain the folders. We'll now go through each one, and copy the files. # Get all files in that directory and copy them.

    [code]my $curNum = 1;
    my $curDir;
    foreach $curDir (@dirs) {
    opendir (DIR, $curDir) || die "Can't access $curDir";
    foreach (readdir(DIR)) {
    # Skip if it ain't a file.
    next unless -f;

    # Get the extension of the file - that's all we want.
    /.(w+)$/;
    my $extensiion = $1;

    # Copy the file.
    copy "$curDir/$_", "$startDir/training$curNum.$extension";

    # Increment our counter.
    $curNum ++;
    }
    closedir;
    }[/code]

    Untested, but fingers crossed... ;-)

    Hope this helps,

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");



  • meshtebmeshteb Posts: 47Member
    Here is my code,with the errors found after compiling this code.


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

    use File::Copy;

    #copy $oldname, $newname;

    my $startFolder = 'E:/timit/train';
    opendir (DIR, $startFolder) || die "Can't access $startFolder";
    my @dirs = ();
    foreach (readdir(DIR))
    {
    # Ignore "special" directories '.' and '..'.
    next if /^.+$/;

    # Do -d test to make sure it is a directory.
    -d && push @dirs, "$startFolder/$_";
    }
    closedir DIR;

    my $curNum = 1;
    my $curDir = 'd:/train;
    foreach $curDir (@dirs){
    opendir (DIR, $curDir) || die "Can't access $curDir";
    foreach (readdir(DIR)) {

    # Skip if it ain't a file.
    next unless -f;

    # Get the extension of the file - that's all we want.
    /.(w+)$/;
    my $extension = wav;

    # Copy the file.
    copy "$curDir/$_", "$startDir/training$curNum.$extension";

    # Increment our counter.
    $curNum ++;
    }
    closedir;
    }


    Hre are the ERRORS after compiling:

    D:Scripts>CopyFiles.pl
    Bareword found where operator expected at D:ScriptsCopyFiles.pl line 23, near "opendir (DIR, $curD
    ir) || die "Can't"
    (Might be a runaway multi-line '' string starting on line 21)
    (Do you need to predeclare opendir?)
    String found where operator expected at D:ScriptsCopyFiles.pl line 34, near "copy ""
    (Might be a runaway multi-line "" string starting on line 23)
    (Missing semicolon on previous line?)
    Unrecognized escape w passed through at D:ScriptsCopyFiles.pl line 23.
    Scalar found where operator expected at D:ScriptsCopyFiles.pl line 34, near "copy "$curDir"
    (Do you need to predeclare copy?)
    String found where operator expected at D:ScriptsCopyFiles.pl line 34, near "$_", ""
    (Missing operator before ", "?)
    Scalar found where operator expected at D:ScriptsCopyFiles.pl line 34, near "", "$startDir"
    (Missing operator before $startDir?)
    String found where operator expected at D:ScriptsCopyFiles.pl line 34, at end of line
    (Missing semicolon on previous line?)
    syntax error at D:ScriptsCopyFiles.pl line 23, near "opendir (DIR, $curDir) || die "Can't access "

    Can't find string terminator '"' anywhere before EOF at D:ScriptsCopyFiles.pl line 34.

  • JonathanJonathan Posts: 2,914Member
    Uh...what did you do with the indentation? This code just looks like a mess now... *sighs*

    : #!/usr/local/bin/perl -w
    :
    : use File::Copy;
    :
    : #copy $oldname, $newname;
    :
    : my $startFolder = 'E:/timit/train';
    : opendir (DIR, $startFolder) || die "Can't access $startFolder";
    : my @dirs = ();
    : foreach (readdir(DIR))
    : {
    : # Ignore "special" directories '.' and '..'.
    : next if /^.+$/;
    :
    : # Do -d test to make sure it is a directory.
    : -d && push @dirs, "$startFolder/$_";
    : }
    : closedir DIR;
    :
    : my $curNum = 1;
    : my $curDir = 'd:/train;
    Well here's your one mistake, you missed of the final '. In my example I just declared this - not assigned to it. You don't need to assign anything to it - we do that in the loop. Leave this line just as:-
    my $curDir;

    : foreach $curDir (@dirs){
    : opendir (DIR, $curDir) || die "Can't access $curDir";
    : foreach (readdir(DIR)) {
    :
    : # Skip if it ain't a file.
    : next unless -f;
    :
    : # Get the extension of the file - that's all we want.
    : /.(w+)$/;
    : my $extension = wav;
    Huh? Leave that as it was too...
    my $extension = $1;
    We capture the extension out of the original filename, on the line above this one.

    : # Copy the file.
    : copy "$curDir/$_", "$startDir/training$curNum.$extension";
    :
    : # Increment our counter.
    : $curNum ++;
    : }
    : closedir;
    : }
    :

    That's the two obvious ones, with the code in that state I won't be surprised if I have missed any others that may exist. Please, always, always, always indent your code neatly and post it here between code tags.

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • meshtebmeshteb Posts: 47Member
    I'm having this error now:

    D:Scripts>CopyFiles.pl
    Not enough arguments for closedir at D:ScriptsCopyFiles.pl line 37, near "closedir;"
    Execution of D:ScriptsCopyFiles.pl aborted due to compilation errors.

    With this code:

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

    use File::Copy;

    #copy $oldname, $newname;

    my $startFolder = 'E:/timit/train';
    opendir (DIR, $startFolder) || die "Can't access $startFolder";
    my @dirs = ();
    foreach (readdir(DIR)) {
    # Ignore "special" directories '.' and '..'.
    next if /^.+$/;

    # Do -d test to make sure it is a directory.
    -d && push @dirs, "$startFolder/$_";
    }
    closedir DIR;

    my $curNum = 1;
    my $curDir;
    foreach $curDir (@dirs) {
    opendir (DIR, $curDir) || die "Can't access $curDir";
    foreach (readdir(DIR)) {
    # Skip if it ain't a file.
    next unless -f;

    # Get the extension of the file - that's all we want.
    /.(w+)$/;
    my $extension =$1;

    # Copy the file.
    copy "$curDir/$_", "$startDir/training$curNum.$extension";

    # Increment our counter.
    $curNum ++;
    }
    closedir;
    }

  • JonathanJonathan Posts: 2,914Member
    [b][red]This message was edited by Jonathan at 2004-1-21 3:0:56[/red][/b][hr]
    : I'm having this error now:
    :
    : D:Scripts>CopyFiles.pl
    : Not enough arguments for closedir at D:ScriptsCopyFiles.pl line 37, near "closedir;"
    : Execution of D:ScriptsCopyFiles.pl aborted due to compilation errors.
    :
    But the question is, did you go look at line 37 to try and figure it out? ;-)

    : With this code:
    :
    : #!/usr/local/bin/perl -w
    :
    : use File::Copy;
    :
    : #copy $oldname, $newname;
    :
    : my $startFolder = 'E:/timit/train';
    : opendir (DIR, $startFolder) || die "Can't access $startFolder";
    : my @dirs = ();
    : foreach (readdir(DIR)) {
    : # Ignore "special" directories '.' and '..'.
    : next if /^.+$/;
    :
    : # Do -d test to make sure it is a directory.
    : -d && push @dirs, "$startFolder/$_";
    : }
    : closedir DIR;
    :
    : my $curNum = 1;
    : my $curDir;
    : foreach $curDir (@dirs) {
    : opendir (DIR, $curDir) || die "Can't access $curDir";
    : foreach (readdir(DIR)) {
    : # Skip if it ain't a file.
    : next unless -f;
    :
    : # Get the extension of the file - that's all we want.
    : /.(w+)$/;
    : my $extension =$1;
    :
    : # Copy the file.
    : copy "$curDir/$_", "$startDir/training$curNum.$extension";
    :
    : # Increment our counter.
    : $curNum ++;
    : }
    : closedir;
    Ooops...should be:-
    closedir DIR;
    As for the other closedir statement.

    : }

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");



  • JonathanJonathan Posts: 2,914Member
    : There is one thing that I did not specify. It seems as if I did not
    : elaborate on it previously. And i'm so sorry for that.This program
    : should copy the .wav files only, not every file in those
    : folders.That is why i did assign that statement to be like this:
    :
    : my $extension = $wav
    :
    : Sorry for inconvinience.
    :
    That change isn't going to work for you, even if you do it right:-

    my $extension = 'wav';

    That'd just take every file and rename it to whatever.wav. Instead, leave that line alone and do this:-

    :
    : # Skip if it ain't a file.
    : next unless [red](-f && /.wav$/i)[/red];
    :
    : # Get the extension of the file - that's all we want.
    : /.(w+)$/;
    : my $extension =$1;
    :

    You can remove the /.(w+)$/; line and just put:-
    my $extension = 'wav';

    But you still must do the other change I told you about too. One change or two...the choice is yours. ;-)

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

Sign In or Register to comment.