81

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
Mofi
  • 46,139
  • 17
  • 80
  • 143
just me
  • 811
  • 1
  • 6
  • 3

11 Answers11

192

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.

Community
  • 1
  • 1
Govert
  • 16,387
  • 4
  • 60
  • 70
  • 11
    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` –  Dec 24 '13 at 16:21
  • 11
    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. – Andrew Cheong May 02 '14 at 09:02
  • 2
    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_. – Andrew Cheong May 02 '14 at 09:07
  • This also worked for renaming my file FYI xcopy Hello.txt test2\Hello2.txt* – SteckDEV Oct 27 '15 at 22:27
  • 4
    Is there a way to always copy as a directory? – Logan Dec 29 '15 at 17:49
  • This does not work for me in windows server 2008, no file is copied – zhihong Dec 22 '16 at 16:19
  • @Logan The `/i` switch serves this purpose. – Kyle Strand Dec 18 '18 at 22:13
  • Great answer. `echo f` is alwful, sometimes when the destination file doesn't exist I should add `echo f`, but other times there is no destination file, I have to add `echo y`. – Zhang Jan 09 '20 at 03:05
22

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
CharlesB
  • 86,532
  • 28
  • 194
  • 218
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\"
Patrick
  • 181
  • 1
  • 2
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
Denis Ivin
  • 5,594
  • 1
  • 26
  • 25
  • 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. – Chuck Wilbur Jul 23 '12 at 15:44
  • 3
    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: http://stackoverflow.com/a/14022309/532647. – Iarek Jan 29 '13 at 12:00
  • 1
    While this breaks on localisations, it's a great example of using pipes. – Tomáš Zato May 20 '15 at 21:44
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.

Shane Lu
  • 1,056
  • 1
  • 12
  • 21
  • This is exactly what I want when setting post-jobs in Visual Studio project building settings. – wanyancan Dec 14 '19 at 13:51
  • 1
    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. – Matt Jul 06 '21 at 08:38
4

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.

Mofi
  • 46,139
  • 17
  • 80
  • 143
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.

Andy Morris
  • 3,393
  • 1
  • 21
  • 20
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.

DosMan
  • 31
  • 4
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.

Kalamarico
  • 5,466
  • 22
  • 53
  • 70
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.
Chad Levy
  • 10,032
  • 7
  • 41
  • 69
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.

grenix
  • 623
  • 7
  • 15