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

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.