The following should do the trick:
@echo off
set Source=C:\Users\siddique.gaffar\Desktop\Artworks
set Target=C:\Users\siddique.gaffar\Desktop\Artworks Copy
set FileList=C:\Users\siddique.gaffar\Desktop\Artwork TXT File\Book1.txt
echo.
if not exist "%Source%" echo Source folder "%Source%" not found & goto Exit
if not exist "%FileList%" echo File list "%FileList%" not found & goto Exit
if not exist "%Target%" md "%Target%"
for /F "usebackq tokens=1-2" %%a in ("%FileList%") do call :CopyFile "%%a" %%b
:Exit
echo.
echo press the Space Bar to close this window.
pause > nul
exit /b 0
:CopyFile
:: first argument = filename
:: second argument = number of copies
REM A little trick that will put limit on 0 if second argument is empty or not a number
set secondarg=%~2
set /a limit=secondarg
REM if limit is invalid (not strict positive), exit the function
IF %limit% LEQ 0 (
echo Invalid number of copies
exit /b 1
)
IF NOT EXIST "%Target%\%~1" (
copy "%Source%\%~1" "%Target%"
IF %limit% LEQ 1 exit /b 0
set /a limit-=1
)
REM File already exists: search correct index for filename
set index=0
set "targetfile=%target%\%~n1"
set file_ext=%~x1
:following
set /a index+=1
Rem if file with index %index% already exists, go back to get following index
IF exist "%targetfile%(%index%).%file_ext%" goto :following
Rem we have the correct index, now we can copy
set /a limit=index+limit-1
FOR /L %%g IN (%index%,1,%limit%) DO copy "%Source%\%~1" "%targetfile%(%%g).%file_ext%"
exit /b 0
Another option if you have long filenames is the use of usebackq
and surrounding the path with double quotes in the for f
loop instead of analyzing the output of the type
command.
The function :CopyFile
checks the existence of the file with an IF EXIST
and uses a counter to find the next index for the filename of the new file. It uses path manipulation to construct a new filename with the index.
EDIT: I've added the possibility to read the number of copies needed from the textfile and specify that number as second argument to the :CopyFile
function. If no number is given or the number is not strict positive (greater than 0), it won't make a copy.
PS: the "little trick" I used that will set %limit%
to 0 in case the second argument is empty works because set
with the /a
flag will replace empty variables with 0. This won't work if you use argument variables directly though:
set /a limit=%~2
will throw an error if the second argument is empty because the cmd parser will substitute %~2
with an empty string and it will execute set /a limit=
which is an invalid assignement using the /a
flag. But if you use an extra variable as transit:
set var=%~2
set /a limit=var
you'll let set
handle the variable expansion and not the cmd interpreter. The set
will see that the var
variable is empty (in the case %2
is empty) and will replace it with 0.