Copy and paste a file in Windows command line like Explorer does it?

If you copy a file in Windows Explorer, and paste into the same folder, Windows automatically renames the copy to avoid a name collision.

MyFile.docx

creates a copy called

MyFile - Copy.docx

Subsequent copies get (n) added.

MyFile - Copy(2).docx

Is there a straightforward way to emulate this behavior using a command-line bat file?

I was thinking of using a date stamp to make the copy unique but that is not nearly as straightforward as I had expected it to be. I’m reviewing code samples for that and I’m sure they work but I can’t understand what the syntax means and I don’t like to use code when I don’t understand every last character.

I don’t know if you’d call it straightforward, but you’d just have to do it all manually. Since you don’t seem to care about the exact format of the files, it’ll be easier just to add a number, so that’s what I’ll do. I’m also going to assume that this is a separate batch file that takes two parameters, the original file and the folder to which it should be copied. (If you need to handle multiple files, wrap it in a “for” command.)


@echo off

setlocal
set filename=%~n1
set ext=%~x1

:LOOP
If exist %newpath%\%filename%%num%%ext% set /a num+=1 && goto loop

copy %1 %2\%filename%%num%%ext%

If you need me to walk you through the code:

“setlocal” makes all environment variables local
“~n” gets just the filename; “%~n1” means just the filename of %1
“~x” gets just the extension, preceded by a dot
“:LOOP” is a label
“If exist” checks if a file exists.
“%num%” is currently blank because I didn’t set it
“set /a” allows me to do arithmetic
“num+=1” adds 1 to %num%
“&&” separates commands on the same line
“goto loop” will go back to the :LOOP label to make sure that file1.ext doesn’t already exist.

And, yes, you can skip all the environment variables and just use %~n1 and %~x1. I used variables to make it easier to understand. You still need to use %num%, though, so keep that “setlocal.”

Better code, wrapped in a for command like I mentioned. (I was bored and the Internet was down.)


@echo off
for %%f in (%1) do call :START "%%~f" "%~2"
GOTO :EOF
:START
setlocal
If exist "%~2\%~n1%~x1" set /a num=2
:LOOP
If exist "%~2\%~n1%num%%~x1" (
	set /a num+=1
	goto loop
)
copy %1 "%~2\%~n1%num%%~x1"

The for command allows you to use any wildcards as %1, and will step through all files, calling :START, which actually begins the work. GOTO :EOF means “go to end of file.” Setlocal now also performs the function of resetting %num% to nothing. I now make sure the first number is 2, and I expanded out the if statement. I got rid of the extra variables for simiplicity’s sake.

BTW, %~1 and similar removes any quotation marks. That’s something I forgot last time.

BigT, thanks so much for this. I have been crazy busy but will try this out today. I don’t understand the variable name syntax–what does the double % in %%f, and what does the ~ do?