Solved Copy all files, if exists, rename & copy

Microsoft Windows xp professional w/serv...
July 7, 2010 at 04:22:45
Specs: Windows XP
Hi, i was wondering if somebody can point me
in the right direction with a problem i have, my
problem is im trying to create a Batch Script
which first of all creates a new folder which will
be called 'Finished', it will then go into and
copy all files in sub folders into this new
'Finished', simple enough, but there will be a
likelyhood of files from different sub folders
which will have the exact same file name as
files which have already been copied to this
'Finished' folder, ive had a play around already
and ive noticed it just overwrites the file if they
have the same file name, which is what i dont
want, and thats where im stuck. i imagine id
want some kind of if statement where if a file
has the same file name as one that has
already been copied, add a (1), (2), (3) ect
ect.. to the end of that file name then copy it.

Ive created a test area with some test files and
this is the batch code ive come up with so far

md Finished
cd folder 1
copy * ..\Finished
cd ..\

cd folder 2
copy * ..\Finished
cd ..\

Im relatively new to creating Batch files but
have a better background on VBA, not sure if
theres a better way than batch script?

ANY help is much appreciated, Thanks.


See More: Copy all files, if exists, rename & copy

Report •

✔ Best Answer
July 13, 2010 at 06:46:37
Alright, try the following (hopefully nothing's lost in
translation):

@echo off

setlocal EnableDelayedExpansion

set DestFolder1=Other
set DestFolder2=Personal Details
set DestFolder3=Emails
set DestFolder4=CSV
set max=4

for /l %%i in (2, 1, %max%) do md "!DestFolder%%i!" 2>nul

for /r %%f in (*) do (
  set CanCopy=true
  set folder=%%~dpf
  if /i "%%f" equ "%~dpnx0" (
    set CanCopy=false
  ) else (
    for /l %%i in (1, 1, %max%) do (
      if /i "%cd%\!DestFolder%%i!\" equ "!folder!" (
        set CanCopy=false
      )
    )
  )
  if "!CanCopy!" equ "true" (
    set DestFolder=Other
    set folder=!folder:~0,-1!
    for /f "delims=" %%d in ("!folder!") do set folder=%%~nd
    for /l %%i in (2, 1, %max%) do (
      if /i "!folder!" equ "!DestFolder%%i!" (
        set DestFolder=!DestFolder%%i!
      )
    )
    if /i "!DestFolder!" equ "Other" md "Other" 2>nul
    if exist "!DestFolder!\%%~nxf" (
      call :GetNextFilename "!DestFolder!\%%~nxf" newfile
      copy "%%f" "!DestFolder!\!newfile!"
    ) else (
      copy "%%f" "!DestFolder!\"
    )
  )
)
call :DeleteFolders
goto :eof

:DeleteFolders
for /f "delims=" %%d in ('dir /b /a:d') do (
  set CanDeleteDir=true
  for /l %%i in (1, 1, %max%) do (
    if /i "!DestFolder%%i!" equ "%%d" (
      set CanDeleteDir=false
    )
  )
  if "!CanDeleteDir!" equ "true" rd /s /q "%%d"
)
goto :eof

:GetNextFilename
set n=0
:loop
set /a n+=1
set %2=%~n1(%n%)%~x1
if exist "%~p1!%2!" goto loop
goto :eof




#1
July 7, 2010 at 12:51:41
Do you want to copy all files (if there are any, and not
including the batch script) from the root folder itself as
well as all sub folders?



Report •

#2
July 7, 2010 at 20:02:13
::-------- EDITED TO FIX OMISSIONS
@echo off & setlocal enabledelayedexpansion
md c:\Finished
cd c:\basedir
for /f %%a in ('dir /b /ad') do (
pushd "%%a"
for /f "tokens=*" %%b in ('dir /b /a-d') do (
set serial=
:aa
if exist "c:\finished\%%b%serial%" set /a serial+=1 & goto :aa
copy "c:\%%a\%%b" "c:\finished\%%b%serial%"
)
popd
)
::----- end script
Mark's question still holds - this is just a tentative stab...
very rough draft!

Report •

#3
July 9, 2010 at 09:22:41
Thanks for your replies, to answer your question i dont mind if
the batch file is copied too, and the end result im looking for
in this script is it'll find, for example, all .pdf files and place it
into a PDF folder which is created at the start of the script, i
only put in my first post the folder named finished as a basic
example on what im looking for this script to do and i was
going to tweak any helpful coding that anyone can give me.

nbrane - Thanks for the code, was much more 'techie' than i
was expecting lol but i broke it down, put in the dir locations
and had a go with it and nothing happened, i stepped into the
code in cmd and got '%%a was unexpected at this time' error
this is what i used:

md Finished
cd folder 1

for /f %%a in ('dir /b /ad') do (
pushd %%a
for /f "tokens=*" %%b in ('dir /b /a-d') do (
set serial=
:aa
if exist "C:\Documents and Settings\mcragg\My
Documents\ORourkeStaffTest\finished\%%b%serial% set /a
serial+=1 & goto :aa
copy "C:\Documents and Settings\mcragg\My
Documents\Test\folder 1\%%a\%%b" "C:\Documents and
Settings\mcragg\My
Documents\Test\finished\%%b%serial%"
)
popd
)
::----- end script


Report •

Related Solutions

#4
July 9, 2010 at 10:06:15
1) I was missing a dbl-quote in line 9: if exist "...%%b%serial
(no closing quote after %serial%, sorry about that)
2) My nextmistake, should have had quotes around line 4 %%a:
pushd "%%a"
3) i think you need delayedexp enabled, (see my revised
response #2 with corrections)
4) When testing from cmd-line, you need single percents instead of double: for /f %a in ...
try these fixes and see if it does anything.

Report •

#5
July 9, 2010 at 12:25:54
The following code (which I wrote the other day, actually,
and had forgotten all about :-)) basically looks through
all sub folders from the current directory for any files and
copies them (adding numbers where necessary) to the
finished folder which it creates in the current
directory. See if you can get what you need from this
and nbrane's response and post back with anything
specific...

@echo off

setlocal EnableDelayedExpansion

set DestFolder=Finished

md "%DestFolder%" 2> nul
for /r %%f in (*) do (
  set CanCopy=false
  set folder=%%~pf
  for %%x in ("!folder:~0,-1!") do set folder=%%~nx
  if /i "!folder!" neq "%DestFolder%" if /i "%%f" neq "%~dpnx0" (
    set CanCopy=true
  )
  if "!CanCopy!" equ "true" (
    if exist "%DestFolder%\%%~nxf" (
      call :GetNextFilename "%DestFolder%\%%~nxf" newfile
      copy "%%f" "%DestFolder%\!newfile!"
    ) else (
      copy "%%f" "%DestFolder%\"
    )
  )
)
goto :eof


:GetNextFilename
set n=0
:loop
set /a n+=1
set %2=%~n1(%n%)%~x1
if exist "%~p1!%2!" goto loop
goto :eof


Report •

#6
July 12, 2010 at 07:36:36
MarkLS, that code worked like a charm for what i was looking
for to start me off, impressed :)

I think i need to read up on batch script a lot more as some of
that code has baffled me, which has made me stuck on where
to tweak it to my needs, i hope you can help.

ill try to do a visual example of what im looking to do below,
might be easier.

Folder structure before script has run

- Test (Folder - Script is here)
- Folder 1 (Folder)
- Personal Details (Folder)
- PD File 1 (File)
- PD File 2 (File)

- CSV (Folder)
- CSV File 1 (File)
- CSV File 2 (File)

- Emails (Folder)
- E File 1 (File)
- E File 2 (File)


- Folder 2 (Folder)
- Personal Details (Folder)
- PD File 1 (File)
- PD File 2 (File)

- CSV (Folder)
- CSV File 1 (File)
- CSV File 2 (File)

- Emails (Folder)
- E File 1 (File)
- E File 2 (File)

Folder structure after script has run

- Test (Folder - Script is here)
- Personal Details (Folder)
- PD File 1 (File)
- PD File 2 (File)
- PD File 3 (File)
- PD File 4 (File)

- CSV (Folder)
- CSV File 1 (File)
- CSV File 2 (File)
- CSV File 3 (File)
- CSV File 4 (File)

- Emails (Folder)
- E File 1 (File)
- E File 2 (File)
- E File 3 (File)
- E File 4 (File)

as an end process i would like to delete the old folders which
have had the files copied out of them, so the folder structure
looks pretty much like above.

There will be free cookies coming your way if you could
supply me with any more of your generous help :) Thanks


Report •

#7
July 13, 2010 at 03:59:10
OK, but what determines what gets copied where? Are the
three ending folder names fixed from the start and files are
copied based on matching folder names or should files be
copied based on extensions (presumably the extensions
are .csv, .eml and, er, ???) ?


Report •

#8
July 13, 2010 at 04:09:26
Yes the folder names are fixed and wont change so everything
that is inside the, for example, Emails folders will all be moved
into the newly created Emails folder which was created at the
start of the script. all files which are in the folder to begin with will
be copied, regardless of file type.

I did get the above description looking a bit better with gaps
under the folders to represent sub folders but it didnt come out
as i'd hoped, sorry. hope this helps.


Report •

#9
July 13, 2010 at 06:46:37
✔ Best Answer
Alright, try the following (hopefully nothing's lost in
translation):

@echo off

setlocal EnableDelayedExpansion

set DestFolder1=Other
set DestFolder2=Personal Details
set DestFolder3=Emails
set DestFolder4=CSV
set max=4

for /l %%i in (2, 1, %max%) do md "!DestFolder%%i!" 2>nul

for /r %%f in (*) do (
  set CanCopy=true
  set folder=%%~dpf
  if /i "%%f" equ "%~dpnx0" (
    set CanCopy=false
  ) else (
    for /l %%i in (1, 1, %max%) do (
      if /i "%cd%\!DestFolder%%i!\" equ "!folder!" (
        set CanCopy=false
      )
    )
  )
  if "!CanCopy!" equ "true" (
    set DestFolder=Other
    set folder=!folder:~0,-1!
    for /f "delims=" %%d in ("!folder!") do set folder=%%~nd
    for /l %%i in (2, 1, %max%) do (
      if /i "!folder!" equ "!DestFolder%%i!" (
        set DestFolder=!DestFolder%%i!
      )
    )
    if /i "!DestFolder!" equ "Other" md "Other" 2>nul
    if exist "!DestFolder!\%%~nxf" (
      call :GetNextFilename "!DestFolder!\%%~nxf" newfile
      copy "%%f" "!DestFolder!\!newfile!"
    ) else (
      copy "%%f" "!DestFolder!\"
    )
  )
)
call :DeleteFolders
goto :eof

:DeleteFolders
for /f "delims=" %%d in ('dir /b /a:d') do (
  set CanDeleteDir=true
  for /l %%i in (1, 1, %max%) do (
    if /i "!DestFolder%%i!" equ "%%d" (
      set CanDeleteDir=false
    )
  )
  if "!CanDeleteDir!" equ "true" rd /s /q "%%d"
)
goto :eof

:GetNextFilename
set n=0
:loop
set /a n+=1
set %2=%~n1(%n%)%~x1
if exist "%~p1!%2!" goto loop
goto :eof



Report •

#10
July 13, 2010 at 07:12:20
You sir, are a genius.

It worked perfectly other than something going wrong with the
files for the Personal Details folder as this was empty after
running the script but the files from that folder were placed
into the Others folder instead.

ive tried adding a random txt file into my test area only into
the Personal Details folder and nowhere else and the end
result was ALL files ended up in the Others folder :S

If i wanted to add more folders to the script at a later stage,
after adding them to the 'set DestFolder5,6,7' ect, would i
need to copy and paste a section of that code again below it
(& changing a few characters here and there) to make it
work?

Much appreciated with your help, your a star!


Report •

#11
July 13, 2010 at 07:43:39
Nevermind, i must of done something wrong as your code is
working perfectly now and i didnt even change anything which is
a bit odd, but hay, kudos goes to you & this forum, i hope karma
is very generous to you one day :)

Report •

#12
July 13, 2010 at 12:07:01
If i wanted to add more folders to the script at a later
stage, after adding them to the 'set DestFolder5,6,7'
ect, would i need to copy and paste a section of that
code again below it (& changing a few characters here
and there) to make it work?

Yep, first off, grab the new code in response #9 which
I've edited slightly and added new variable 'max'. All you
need do when adding a new folder is add to the list of
'set DestFolder#=' and increment the max var.



Report •

Ask Question