84

I have a simple copy from-to script for one of my friends who is missing a file 20 km from my desk.

When testing the script out I am prompted if my file shapes.atc is a file or a folder.

I can tell you that its a file. How can I automatically copy it with my friend needs to just double click the batch to get the file copying job done.

xcopy /s/y J:\"My Name"\"FILES IN TRANSIT"\JOHN20101126\"Missing file"\Shapes.atc C:\"Documents and Settings"\"His name"\"Application Data"\Autodesk\"AutoCAD 2010"\"R18.0"\enu\Support\Shapes.atc
1

12 Answers 12

195

A seemingly undocumented trick is to put a * at the end of the destination - then xcopy will copy as a file, like so

xcopy c:\source\file.txt c:\destination\newfile.txt*

The echo f | xcopy ... trick does not work on localized versions of Windows, where the prompt is different.

Sign up to request clarification or add additional context in comments.

8 Comments

Beware there is a potential problem when using the * character. I tried copying and renaming the file with a single command using the suggested tip. The source file was named Android.mk.armeabi.debug. The target name was Android.mk. The resulting filename was Android.mkbug
Thanks for this! I actually ran into an error, "Could not expand second file name so as to match first", which only had 6 Google hits (and no answers). It took a while, but I figured it out, and it also explains @user1222021's observation. The source and target extensions to be the same length. If the target extension is shorter, e.g. .shtml to .html*, the target will "gain" letters as if laid on top of the source extension, e.g. .htmll. If the target extension is longer, then you get the above error.
That "layover" effect strongly suggests that the developer(s) allocated a buffer based on the source extension's length, then reused the buffer to store the target extension's length without null-terminating the C-string. Presumably, the developer(s) assumed that no one would change the extensions of files being copied, maybe because back then (xcopy first released in 1985, though I'm sure it's been rewritten since), it wasn't nearly as popular as it is now (if it was known at all) to use alternate extensions to indicate variations of a file. People back then just used different filenames.
This also worked for renaming my file FYI xcopy Hello.txt test2\Hello2.txt*
Is there a way to always copy as a directory?
|
23

Actually xcopy does not ask you if the original file exists, but if you want to put it in a new folder named Shapes.atc, or in the folder Support (which is what you want.

To prevent xcopy from asking this, just tell him the destination folder, so there's no ambiguity:

xcopy /s/y "J:\Old path\Shapes.atc" "C:\Documents and Settings\his name\Support"

If you want to change the filename in destination just use copy (which is more adapted than xcopy when copying files):

copy /y "J:\Old path\Shapes.atc" "C:\Documents and Settings\his name\Support\Shapes-new.atc

6 Comments

+1 for the copy rather than xcopy suggestion :)
But copy won't create the path if it doesn't exist, of course.
And copy won't print what it's doing (aka cp -v).
If you specify the destinaiton as a directory, you can add a trailing backslash - this prevents questions if the directory doesn't exist. (the filename stays the same)
thanks, took me 20+ mins to figure out such simple thing, do not need to create a new folder, and it suprise me that xcopy just dose not work easily to auto copy, rename and overwrite a file
|
18

The real trick is: Use a Backslash at the end of the target path where to copy the file. The /Y is for overwriting existing files, if you want no warnings.

Example:

xcopy /Y "C:\file\from\here.txt" "C:\file\to\here\"

Comments

13
echo f | xcopy /s/y J:\"My Name"\"FILES IN TRANSIT"\JOHN20101126\"Missing file"\Shapes.atc C:\"Documents and Settings"\"His name"\"Application Data"\Autodesk\"AutoCAD 2010"\"R18.0"\enu\Support\Shapes.atc

3 Comments

I had a similar problem involving .zip files instead of .atc, and this is the only answer of the 3 posted here that actually worked.
This solution might not work on some Windows localization. Alternatively you can append an asterisk to destination file name and xcopy won't ask anything. A bit more details here: stackoverflow.com/a/14022309/532647.
While this breaks on localisations, it's a great example of using pipes.
8

Referencing XCopy Force File

For forcing files, we could use pipeline "echo F |":

C:\Trash>xcopy 23.txt 24.txt
Does 24.txt specify a file name
or directory name on the target
(F = file, D = directory)?

C:\Trash>echo F | xcopy 23.txt 24.txt
Does 24.txt specify a file name
or directory name on the target
(F = file, D = directory)? F
C:23.txt
1 File(s) copied

For forcing a folder, we could use /i parameter for xcopy or using a backslash() at the end of the destination folder.

2 Comments

This is exactly what I want when setting post-jobs in Visual Studio project building settings.
Be aware there is a localization issue with that - it works for englisch Windows versions, but for example on a German Windows it will be "d = file (datei), v = directory (verzeichnis)", so you would write echo d | xcopy 23.txt 24.txt instead.
5

Well, for the task as asked by just me the perhaps best solution would be the following command according to the incomplete advice of Andy Morris:

xcopy "J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file\Shapes.atc" "C:\Documents and Settings\His name\Application Data\Autodesk\AutoCAD 2010\R18.0\enu\Support\" /Q /R /S /Y

This works for this simple file copying task because of

  • specifying just the destination directory instead of destination file and
  • ending destination directory with a backslash which is very important as otherwise XCOPY would even with /I prompt for file or directory on copying just a single file.

The other parameters not related to the question are:

  • /Q ... quiet
  • /Y ... yes (OS language independent) on overwrite existing file
  • /R ... overwrite also read-only, hidden and system file
  • /S ... from specified directory and all subdirectories.

Well, I don't know if /S is really needed here because it is unclear if just J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file\Shapes.atc should be copied or all Shapes.atc found anywhere in directory tree of J:\My Name\FILES IN TRANSIT\JOHN20101126\Missing file.

The explanation for the parameters can be read by opening a command prompt window and running from within this window xcopy /? to get output the help for XCOPY.


But none of the provided solutions worked for a file copying task on which a single file should be copied into same directory as source file, but with a different file name because of current date and time is inserted in file name before file extension.

The source file can have hidden or system attribute set which excludes the usage of COPY command.

The batch file for creating the time stamped file should work also on Windows XP which excludes ROBOCOPY because by default not available on Windows XP.

The batch file should work with any file including non typical files like .gitconfig or .htaccess which are files without a file extension starting with a point to hide them on *nix systems. Windows command processor interprets such files as files with no file name and having just a file extension because of the rule that everything after last point is the extension of the file and everything before last point is the file name.

For a complete task description and the final, fully commented solution see the post Create a backup copy of files in UltraEdit forum.

Patrick's, Interociter Operator's and CharlesB's solutions do not work because using /Y does not avoid the file or directory prompt if the destination file does not already exist.

Andy Morris' and grenix's solutions can't be used for the single file copying task as destination must be the name of destination file and not the name of destination directory. The destination directory is the same as the source directory, but name of destination file is different to name of source file.

DosMan's and Govert's solutions simply don't work for files starting with a point and not having a file extension.

For example the command

xcopy C:\Temp\.gitconfig C:\Temp\.gitconfig_2016-03-07_15-30-00* /C /H /K /Q /R /V /Y

results in following error message on execution:

English:  Could not expand second file name so as to match first.
German: Zweiter Dateiname konnte nicht so erweitert werden, dass er zum ersten passt.

And finally Denis Ivin's solution has the restriction that the operating system language dependent character for an automatic answering of the file OR directory prompt must be known.

So I thought about methods to get F for File on English Windows or D for Datei on German Windows or ? for ... on ... Windows automatically.

And it is indeed possible to determine the language dependent character for an automatic answering of the prompt.

A hack is used to get the language dependent letter from prompt text without really copying any file.

Command XCOPY is used to start copying the batch file itself to folder for temporary files with file extension being TMP for destination file. This results in a prompt by XCOPY if there is not already a file with that name in temporary files folder which is very unlikely.

The handler of device NUL is used as an input handler for XCOPY resulting in breaking the copying process after the prompt was output by XCOPY two times.

This output is processed in a FOR loop which is exited on first line starting with an opening parenthesis. This is the line on which second character defines the letter to use for specifying that destination is a file.

Here is a batch file using XCOPY with the code to determine the required letter for an automatic answering of the file or directory prompt to create a time stamped copy of a single file in same directory as the source file even if source file is a hidden or system file and even if the source file starts with a point and does not have a file extension.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Batch file must be started or called with name of a single file.

if "%~1" == "" exit /B
for /F "delims=*?" %%I in ("#%~1#") do if not "%%I" == "#%~1#" exit /B
if not exist "%~1" exit /B
if exist "%~1\" exit /B

rem Determine the character needed for answering prompt of
rem XCOPY for destination being a file and not a directory.

del /F "%TEMP%\%~n0.tmp" 2>nul
for /F %%I in ('%SystemRoot%\System32\xcopy.exe "%~f0" "%TEMP%\%~n0.tmp" ^<nul') do (
    set "PromptAnswer=%%I"
    setlocal EnableDelayedExpansion
    if "!PromptAnswer:~0,1!" == "(" set "PromptAnswer=!PromptAnswer:~1,1!" & goto CopyFile
    endlocal
)
echo ERROR: Failed to determine letter for answering prompt of XCOPY.
exit /B

:CopyFile
endlocal & set "PromptAnswer=%PromptAnswer%"
rem This is a workaround for files starting with a point and having no
rem file extension like many hidden files on *nix copied to Windows.

if "%~n1" == "" (
    set "FileNameWithPath=%~dpx1"
    set "FileExtension="
) else (
    set "FileNameWithPath=%~dpn1"
    set "FileExtension=%~x1"
)

rem Get local date and time in region and language independent format YYYYMMDDHHmmss
rem and reformat the local date and time to format YYYY-MM-DD_HH-mm-ss.

for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS get LocalDateTime /format:value') do set "LocalDateTime=%%I"
set "LocalDateTime=%LocalDateTime:~0,4%-%LocalDateTime:~4,2%-%LocalDateTime:~6,2%_%LocalDateTime:~8,2%-%LocalDateTime:~10,2%-%LocalDateTime:~12,2%"

rem Do the copy with showing what is copied and with printing success or
rem an error message if copying fails for example on sharing violation.

echo Copy "%~f1" to "%FileNameWithPath%_%LocalDateTime%%FileExtension%"

for /F %%I in ('echo %PromptAnswer% ^| %SystemRoot%\System32\xcopy.exe "%~f1" "%FileNameWithPath%_%LocalDateTime%%FileExtension%" /C /H /K /Q /R /V /Y') do set "FilesCopied=%%I"

if "%FilesCopied%" == "1" (echo Success) else echo ERROR: Copying failed, see error message above.

This batch code was tested on German Windows XP SP3 x86 and English Windows 7 SP1 x64.

See the post Create a backup copy of files in UltraEdit forum for a similar, fully commented batch file explaining all parts of the batch code.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • del /?
  • echo /?
  • exit /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?
  • wmic OS get /?
  • xcopy /?

Further the Microsoft article about Using command redirection operators should be read, too.

Comments

3

The /i switch might be what your after.

From xcopy /?

/I If destination does not exist and copying more than one file, assumes that destination must be a directory.

1 Comment

This flag does the opposite of what the OP is after: it tells xcopy to assume a directory, not assume a file.
2

The trick of appending "*" can be made to work when the new extension is shorter. You need to pad the new extension with blanks, which can only be done by enclosing the destination file name in quotes. For example:

xcopy foo.shtml "foo.html *"

This will copy and rename without prompting.

"That's not a bug, it's a feature!" (I once saw a VW Beetle in the Microsoft parking lot with the vanity plate "FEATURE".) These semantics for rename go all the way back to when I wrote DOS v.1. Characters in the new name are substituted one by one for characters in the old name, unless a wildcard character (? or *) is present in the new name. Without adding the blank(s) to the new name, remaining characters are copied from the old name.

Comments

1

I had exactly the same problem, where is wanted to copy a file into an external hard drive for backup purposes. If I wanted to copy a complete folder, then COPY was quite happy to create the destination folder and populate it with all the files. However, I wanted to copy a file once a day and add today's date to the file. COPY was happy to copy the file and rename it in the new format, but only as long as the destination folder already existed.

my copy command looked like this:

COPY C:\SRCFOLDER\MYFILE.doc D:\DESTFOLDER\MYFILE_YYYYMMDD.doc

Like you, I looked around for alternative switches or other copy type commands, but nothing really worked like I wanted it to. Then I thought about splitting out the two different requirements by simply adding a make directory ( MD or MKDIR ) command before the copy command.

So now i have

MKDIR D:\DESTFOLDER

COPY C:\SRCFOLDER\MYFILE.doc D:\DESTFOLDER\MYFILE_YYYYMMDD.doc

If the destination folder does NOT exist, then it creates it. If the destination folder DOES exist, then it generates an error message.. BUT, this does not stop the batch file from continuing on to the copy command.

The error message says: A subdirectory or file D:\DESTFOLDER already exists

As i said, the error message doesn't stop the batch file working and it is a really simple fix to the problem.

Hope that this helps.

Comments

0
xcopy /s/y J:\"My Name"\"FILES IN TRANSIT"\JOHN20101126\"Missing file"\Shapes.atc C:\"Documents and Settings"\"His name"\"Application Data"\Autodesk\"AutoCAD 2010"\"R18.0"\enu\Support\*.*"

..should do it.

Good idea to do an:

IF NOT EXIST "C:\Documents and Settings\His name\Application Data\Autodesk\AutoCAD 2010\R18.0\enu\Support\Shapes.atc" ECHO/ && ECHO/ && ECHO * * * * * COPY FAILED - Call JustME at 555-555-1212 && ECHO/ && pause

(assuming you've done a rename of previous version to .old)

XCOPY  /Z  <----- restartable mode - good for large files.

Comments

0

The virtual parent trick

Assuming you have your source and destination file in

%SRC_FILENAME% and %DST_FILENAME%

you could use a 2 step method:

@REM on my win 7 system mkdir creates all parent directories also
mkdir "%DST_FILENAME%\.."
xcopy "%SRC_FILENAME% "%DST_FILENAME%\.."

this would be resolved to e.g

mkdir "c:\destination\b\c\file.txt\.."
@REM The special trick here is that mkdir can create the parent
@REM directory of a "virtual" directory (c:\destination\b\c\file.txt\) that 
@REM doesn't even need to exist.
@REM So the directory "c:\destination\b\c" is created here.
@REM mkdir "c:\destination\b\c\dummystring\.." would have the same effect

xcopy "c:\source\b\c\file.txt" "c:\destination\b\c\file.txt\.."
@REM xcopy computes the real location of  "c:\destination\b\c\file.txt\.."
@REM which is the now existing directory "c:\destination\b\c"
@REM (the parent directory of the "virtual" directory c:\destination\b\c\file.txt\).

I came to the idea when I stumbled over some really wild ../..-constructs in the command lines generated from a build process.

Comments

0

Because destination path does not exist and so can be a file or a folder.

To avoid the question you can just check it before the xcopy:

rem test on a path existence
if exist "dst" ...

rem test on a directory existence
if exist "dst\*" ...

rem test on a file existence
if exist "dst" if not exist "dst\*" ...

rem create a file to copy to `dst` as a file
if not exist "dst" type nul > dst
rem with overwrite
xcopy ... /Y src dst ...

rem create a directory to copy into `dst` directory
if not exist "dst" mkdir dst
rem without overwrite
xcopy ... src dst ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.