|
|
|
.bat program to copy recursively
|
Original Message
|
Name: giovanigonzales
Date: July 9, 2007 at 19:36:43 Pacific
Subject: .bat program to copy recursivelyOS: Windows XPCPU/Ram: 512Model/Manufacturer: DELL |
Comment: Hello, I need a script to copy a directory recursively, but instead of re-creating the tree structure, to copy all files in a single folder, appending the directories names as sufix to the file names. For example i have: sourcedir: folder01: file1, file2, file3 folder02: file1, file2, file3 the result must be: destdir: folder01_file1, folder01_file2, folder01_file3, folder02_file1, folder02_file2, folder02_file3 I know how to do that in .bash but i need a .bat file to do it also, and I'm not good at all in Windows batch scripting many thanks
Report Offensive Message For Removal
|
|
Response Number 1
|
Name: Mechanix2Go
Date: July 10, 2007 at 08:04:04 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Try this. After previewing, remove the echo before copy to activate it. ::== recurc.bat :: copies all files in tree to dest, prepending orig DIRname @echo off setLocal EnableDelayedExpansion set /p src=source ? set /p dest=dest ? pushd !src! for /f "tokens=* delims= " %%a in ('dir/b/ad') do ( pushd %%a set DN=%%a for /f "tokens=* delims= " %%F in ('dir/b/a-d') do ( echo copy %%F !dest!\!DN!%%F ) popd ) ::== ===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
|
Response Number 2
|
Name: Mechanix2Go
Date: July 10, 2007 at 12:38:51 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)After thinking about this for a while, I see that it hets ONLY the files in dirs immediately below src. If it needs to go deeper, that will take more doing.
===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
|
Response Number 4
|
Name: giovanigonzales
Date: July 11, 2007 at 02:46:47 Pacific
Subject: .bat program to copy recursively |
Reply: (edit) thank you for the response, i tried the script and indeeed it does not recurse into source directories so the output is: copy file1 c:\dest\dir1file1 copy file2 c:\dest\dir1file2 copy file3 c:\dest\dir1file3 copy file1 c:\dest\dir2file1 copy file2 c:\dest\dir2file2 copy file3 c:\dest\dir2file3
i already use bash with msys from www.mingw.org , but i need to do this recursive copy a lot of times and its annoying to start msys , entering the source directory every time, etc. a .bat script would save a lot of time You think is possilble to make a .bat file like this? C:\msys\1.0\msys.bat rcopy.sh I think rsim not the first peon that needs this kind of script, any sugestion for keywords to search on google? i tried a lot of searches and now im out of ideas
Report Offensive Follow Up For Removal
|
|
Response Number 5
|
Name: FishMonger
Date: July 11, 2007 at 07:47:12 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)I've never used MinGW, so I don't know how much overhead it uses to load its environment, but yes, you can use a batch file as a wrapper. However, I think it might be more efficient to use Perl. Here's a script that does what you need. ========================================== #!perl use strict; use warnings; use File::Find; use File::Copy; # change these assignments as needed my $srcdir = 'C:/temp'; my $destdir = 'C:/test/folder'; finddepth(\&wanted, $srcdir); sub wanted {      return if -d;      my ($file) = $File::Find::name =~ /^...(.+)$/;      $file =~ s~/~_~g;      copy($File::Find::name, "$destdir/$file"); }
Report Offensive Follow Up For Removal
|
|
Response Number 6
|
Name: giovanigonzales
Date: July 11, 2007 at 10:15:47 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Awesome! it works really nice. If possible, i would like some improvements: before begining, remove all content in destination dir (like "rm -rf $dest") - with no error if it doesnt exists create destination dir with parents if they dont exist (like "mkdir -p $dest") can i define $srcdir as current dir? (".") I tried with $srcdir = '.'; or './' but doesnt work. I need to run the script from the current directory and also that will remove the unnecesary prefix "temp" from the files names (considering that $srcdir="C:/temp") muchas gracias!
Report Offensive Follow Up For Removal
|
|
Response Number 7
|
Name: FishMonger
Date: July 11, 2007 at 10:21:00 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Yep, those adjustments are easy. I'm just leaving for work, but I'll post back later today when I have more time.
Report Offensive Follow Up For Removal
|
|
Response Number 8
|
Name: FishMonger
Date: July 11, 2007 at 12:40:32 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Part of your requested adjustments implies deleting the dest dir each time the script runs. That's easy to do, but it may not be necessary. Try this: =========================================== #!perl use strict; use warnings; use File::Find; use File::Copy; use File::Path; # change these assignments as needed my $srcdir = './'; my $destdir = 'C:/test/folder'; mkpath $destdir unless -d $destdir; unlink <$destdir/*>; finddepth(\&wanted, $srcdir); sub wanted {      return if -d;      my ($file) = $File::Find::name =~ /^$srcdir(.+)$/;      $file =~ s~/~_~g;      print "Coping: $File::Find::name \n To: $destdir/$file\n";      copy($File::Find::name, "$destdir/$file"); }
Report Offensive Follow Up For Removal
|
|
Response Number 9
|
Name: giovanigonzales
Date: July 11, 2007 at 13:32:43 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)now it does not copy the files from the subdirectories, but if I assign to $srcdir an absolute path (like "my $srcdir = 'C:/src';") then it works (appending an "_" as prefix to the file names) I allways copy files to the same destination directory - from wihch i move files to final destination, and it should not be mixed with the files from previous copy, so that was really usefull - to empty it every time, thanks for that
Report Offensive Follow Up For Removal
|
|
Response Number 10
|
Name: FishMonger
Date: July 11, 2007 at 14:40:56 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Hmmm...I guess I should have tested after adjusting the script. It looks link there's a gotcha when using a relative path. I'll need to review the module's documentation. If the script is in the same directory as the src files, it might be best to skip over it in the sub. Add this return statement just after the other one in the sub. return if $0 =~ /$_$/; There are other improvements that I could suggest, but it all depends on what you need/want.
Report Offensive Follow Up For Removal
|
|
Response Number 11
|
Name: FishMonger
Date: July 11, 2007 at 14:44:17 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)>> if I assign to $srcdir an absolute path (like "my $srcdir = 'C:/src';") then it works (appending an "_" as prefix to the file names) To get rid of the leading _ in the filename, just add the trailing / to the $srcdir i.e., my $srcdir = 'C:/src/';
Report Offensive Follow Up For Removal
|
|
Response Number 12
|
Name: giovanigonzales
Date: July 11, 2007 at 15:38:42 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Hi, The script is named rcopy.pl and it is in the "C:\Windows\System32" directory also there i have a rcopy.bat: "C:\Program Files\Perl\bin\perl.exe" C:\Windows\System32\rcopy.pl I placed them there for being in the %PATH% Any sugestions for improvements would be nice. Maybe I will need some other things later that I dont realize now. I added the line "return if $0 =~ /$_$/;" right after the line "copy($File::Find::name, "$destdir/$file");" but seems no difference to me
Report Offensive Follow Up For Removal
|
|
Response Number 13
|
Name: FishMonger
Date: July 11, 2007 at 20:26:42 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)That second return statement would only be needed if the script was in the same directory as the files that are being copied. If you do need it, it would be moved up a few lines, like this: sub wanted {     return if -d;     return if $0 =~ /$_$/; .... .... .... } Improvements: One of the main problems I see in a lot of scripts is the lack of error handling. A well written program (or script) would have a copious amount of error handling and in some cases the error handling would be more complex than the base code. Obviously, forums such as this are not designed to provide fully developed production level code. 2 areas of error checking that you want to consider are 1) verify that the mkpath command was successful, and 2) verify that the file copy was successful. You may want to generate log entires at each step. Instead of hard coding the src & dest directories, pass them as command line parameters. Print a usage statement if missing arguments or wrong type of arguments. Add comments to any statement that may not be self explanatory.
Report Offensive Follow Up For Removal
|
|
Response Number 14
|
Name: Mechanix2Go
Date: July 12, 2007 at 00:44:50 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)"One of the main problems I see in a lot of scripts is the lack of error handling. A well written program (or script) would have a copious amount of error handling and in some cases the error handling would be more complex than the base code. Obviously, forums such as this are not designed to provide fully developed production level code." Hi FM Can I use that for my tag line? I'll work om the bat.
===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
|
Response Number 15
|
Name: giovanigonzales
Date: July 12, 2007 at 06:58:56 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Thanks a lot FishMonger! The script is very usefull to me as it is now. The option to define $srcdir = "./" is not so important atm. Im using the same source dir every time. Anyways if you ever find a work around, I would be happy to see it. Also i wont need any error handling in the forseable future as im not using the script for critical things
Report Offensive Follow Up For Removal
|
|
Response Number 16
|
Name: FishMonger
Date: July 12, 2007 at 10:29:12 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)giovanigonzales, Glad I was able to help! ---------- Hi M2, Feel free to use it as your tag line, but it's a little wordy, don't you think! :-)
Report Offensive Follow Up For Removal
|
|
Response Number 17
|
Name: Mechanix2Go
Date: July 16, 2007 at 05:30:51 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)It took a while to marinate. ::== recur2a.bat @echo off setLocal EnableDelayedExpansion set src=c:\util set dest=p:\stuff pushd !src! for /f "tokens=* delims= " %%a in ('dir/s/b/ad') do ( pushd %%a copy . !dest! > nul 2> nul popd )
===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
|
Response Number 18
|
Name: giovanigonzales
Date: July 17, 2007 at 15:18:47 Pacific
Subject: .bat program to copy recursively |
Reply: (edit) thanks, but it does not add the prefix so if there are more files with the same name in different subdirectories, it will overwrite them. also ignores files in the src directory
Report Offensive Follow Up For Removal
|
|
Response Number 19
|
Name: Mechanix2Go
Date: July 21, 2007 at 05:18:42 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)I think I got it right. I put a - before filename for readability. ::== cprecur9.bat :: lesson learned : !CD! **** note redir stderr: 2> NO SPACE :: copy recur all files in tree to dest dir :: prepend old dir name :: credit to IVO for the code in :sub1 @echo off setLocal EnableDelayedExpansion set logdir=%CD% set src=c:\util set dest=p:\stuff pushd !src! call :sub1 for /f "tokens=* delims= " %%a in ('dir/b/a-d 2^>nul') do ( copy "%%a" "!dest!\!RD!-%%a" > nul 2> nul ) for /f "tokens=* delims= " %%a in ('dir/s/b/ad') do ( pushd %%a call :sub1 for /f "tokens=* delims= " %%a in ('dir/b/a-d 2^>nul') do ( copy "%%a" "!dest!\!RD!-%%a" > nul 2> nul ) popd ) goto :eof :sub1 Set CF=%CD% Set RD= :LOOP If "%CF:~-1,1%"=="\" GoTo :DONE Set RD=%CF:~-1,1%%RD% Set CF=%CF:~0,-1% GoTo :LOOP :DONE goto :eof ::== done ===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
|
Response Number 20
|
Name: giovanigonzales
Date: July 25, 2007 at 10:08:07 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)wow! the windows batch code looks defenately horrible comparing to .bash or .perl hehe Sorry, but still the way it adds prefixes is not good, it can easily overwrite files because it does not add all the parent directories path to the prefix, only the last parent. this is the way it works: SRC: dir1 subdir1 file1 file2 file3.txt result: subdir1_file1 subdir2_file2 SRC_file3.txt and the result should be: dir1_subdir1_file1 dir1_subdir1_file2 file3.txt
Report Offensive Follow Up For Removal
|
|
Response Number 21
|
Name: Mechanix2Go
Date: July 29, 2007 at 04:12:04 Pacific
Subject: .bat program to copy recursively |
Reply: (edit):: copy recur all files in tree to dest dir :: prepend old dir name @echo off setLocal EnableDelayedExpansion set src=c:\files set dest=s:\stuff pushd !src! for /f "tokens=* delims= " %%a in ('dir/b/a-d 2^>nul') do ( copy "%%a" "!dest!\%%a" > nul 2> nul ) for /f "tokens=* delims= " %%a in ('dir/s/b/ad') do ( set P=%%a set P=!P:~3,99! set P=!P:\=_! pushd %%a for /f "tokens=* delims= " %%a in ('dir/b/a-d 2^>nul') do ( copy "%%a" "!dest!\!P!_%%a" > nul 2> nul ) popd )
===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
|
Response Number 22
|
Name: giovanigonzales
Date: August 1, 2007 at 15:12:37 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Seems you took it as a personal chalenge heh. Now it works fine. Thanks a lot! Nice piece of software I would say. Just for the sake of perfection I would point that the result is: src_dir1_subdir1_file1 src_dir1_subdir1_file2 file3.txt and its not suposed to prepend "src_" and if src="c:\dir1\dir2\dir3" for example then it would prepend "dir1_dir2_dir3" to all files Anyways the program is just perfect for me as it is now, many thanks!
Report Offensive Follow Up For Removal
|
|
Response Number 23
|
Name: Mechanix2Go
Date: August 2, 2007 at 01:09:31 Pacific
Subject: .bat program to copy recursively |
Reply: (edit)Glad we came out alive. ===================================== If at first you don't succeed, you're about average.M2
Report Offensive Follow Up For Removal
|
Use following form to reply to current message:
|
|

|