125

I just can't seem to find a way on the command line to say "copy all the files from directory A to directory B, but if the file already exists in directory B, don't overwrite it, no matter which file is newer, and don't prompt me."

I have been through copy, move, xcopy & robocopy, and the closest I can get is that you can tell robocopy "copy A to B, but don't overwrite newer files with older files," but that doesn't work for me. I looked at xxcopy, but discarded it, as I don't want to have a third-party dependency on a Visual Studio post-build event that will require other SVN users to have that tool installed in order to do the build.

I want to add a command line to the post-build event in Visual Studio 2010 so that the files that are generated from the T4 templates for new EF model objects get distributed to the project folders to which they belong, but regenerated files for existing objects don't overwrite potentially edited destination files.

Since the T4 template regenerates, the source file is always newer, and I can't use the "newer" switch reliably, I don't think.

I use partial classes for those items for which I can, but there are other things I generate that can't use partial classes (e.g. generating a default EditorTemplate or DisplayTemplate *.ascx file).

Any one have any similar problems they have solved?

1
  • Are you familiar with cmd.exe's for command? If not, I recommend you run for /? and use that.
    – Gabe
    Commented Nov 19, 2010 at 19:54

14 Answers 14

250

Robocopy, or "Robust File Copy", is a command-line directory replication command. It has been available as part of the Windows Resource Kit starting with Windows NT 4.0, and was introduced as a standard feature of Windows Vista, Windows 7 and Windows Server 2008.

   robocopy c:\Sourcepath c:\Destpath /E /XC /XN /XO

To elaborate (using Hydrargyrum, HailGallaxar and Andy Schmidt answers):

  • /E makes Robocopy recursively copy subdirectories, including empty ones.
  • /XC excludes existing files with the same timestamp, but different file sizes. Robocopy normally overwrites those.
  • /XN excludes existing files newer than the copy in the destination directory. Robocopy normally overwrites those.
  • /XO excludes existing files older than the copy in the destination directory. Robocopy normally overwrites those.

With the Changed, Older, and Newer classes excluded, Robocopy does exactly what the original poster wants - without needing to load a scripting environment.

References: Technet, Wikipedia
Download from: Microsoft Download Link (Link last verified on Mar 30, 2016)

5
  • By 'exclude' do you mean 'skip' or 'delete/remove'?
    – airstrike
    Commented Oct 14, 2013 at 17:37
  • @Andre Terra: Skip, normally. If you're using the /MIR flag, it might remove them. I haven't tested that. Commented Dec 4, 2013 at 23:33
  • With /MIR, files that don't exist in the source are indeed removed. But when also using /XN and /XO, files that exist in both places are simply skipped (not sure whether size is checked). This is ideal for my situation where I need to copy either a newer or older version of my application but where the dateModified stamps of the libraries the application uses are incorrect yet the file names themselves contain their version number. Commented Aug 5, 2015 at 11:18
  • 1
    Is it necessary to include /e? What if you use /s instead? I don't want a bunch of empty sub-folders.
    – Arete
    Commented Feb 4, 2020 at 20:03
  • /S instead of /E is totally fine. It does as it lists in the documentation (don't include emtpy subdirs).
    – ricekab
    Commented Feb 24, 2021 at 10:56
60

You can try this:

echo n | copy /-y <SOURCE> <DESTINATION>

-y simply prompts before overwriting and we can pipe n to all those questions. So this would in essence just copy non-existing files. :)

4
  • 2
    Beautifully simple.
    – Holf
    Commented Nov 1, 2016 at 14:25
  • 8
    why does it answer all the questions when we only pipe once?
    – phuclv
    Commented May 27, 2017 at 11:48
  • Awesome, I went with this option. Before thinking of piping, I googled for a parameter I thought I was missing and then I came across this page. Trying this solution I noticed that when piping, copy apparently enables the /Y parameter, so that's why /-Y must be added.
    – Andrew
    Commented Jul 7, 2017 at 20:46
  • 4
    @phuclv It seems copy /-y just automatically assumes No once stdin runs out of input. You can omit the first explicit n, or pipe < nul into it, and the same thing happens.
    – mwfearnley
    Commented Nov 8, 2019 at 10:03
52

Belisarius' solution is good.

To elaborate on that slightly terse answer:

  • /E makes Robocopy recursively copy subdirectories, including empty ones.
  • /XC excludes existing files with the same timestamp, but different file sizes. Robocopy normally overwrites those.
  • /XN excludes existing files newer than the copy in the source directory. Robocopy normally overwrites those.
  • /XO excludes existing files older than the copy in the source directory. Robocopy normally overwrites those.

With the Changed, Older, and Newer classes excluded, Robocopy does exactly what the original poster wants - without needing to load a scripting environment.

42
For %F In ("C:\From\*.*") Do If Not Exist "C:\To\%~nxF" Copy "%F" "C:\To\%~nxF"
4
  • 5
    This worked for me, but I had to use two percent symbols instead of one as I was running this from inside a batch file rather than the command line. I replaced instances of %F with %%F and instances of %~nxF with %%~nxF.
    – Owen
    Commented Jun 17, 2016 at 7:37
  • 2
    What does ~nx in %~nxF exactly mean? Commented Aug 27, 2016 at 17:21
  • @stu, it only says that for ~nxF the variable F turns into a file name and an extension. Commented Aug 29, 2016 at 13:07
  • Yes, so effectively, give me the filename+extension, without the path -- which is what you need to do the test in the target folder and specify the target filename. The point is that %F includes the path, and you don't want it there.
    – Stu
    Commented Aug 30, 2016 at 13:27
6

Here it is in batch file form:

@echo off
set source=%1
set dest=%2
for %%f in (%source%\*) do if not exist "%dest%\%%~nxf" copy "%%f" "%dest%\%%~nxf"
0
5

There is an odd way to do this with xcopy:

echo nnnnnnnnnnn | xcopy /-y source target

Just include as many n's as files you're copying, and it will answer n to all of the overwrite questions.

1
  • 2
    Regarding copy, see this answer, specifically @mwfearnley comment: copy /-y automatically assumes n once stdin is exhausted, so you can e.g. echo n only once and it still works.
    – rsenna
    Commented Nov 14, 2019 at 12:07
4

I just want to clarify something from my own testing.

@Hydrargyrum wrote:

  • /XN excludes existing files newer than the copy in the source directory. Robocopy normally overwrites those.
  • /XO excludes existing files older than the copy in the source directory. Robocopy normally overwrites those.

This is actually backwards. XN does "eXclude Newer" files but it excludes files that are newer than the copy in the destination directory. XO does "eXclude Older", but it excludes files that are older than the copy in the destination directory.

Of course do your own testing as always.

2
  • 2
    Is this an answer to the original question, or a comment on someone else's answer?
    – ASGM
    Commented Apr 16, 2013 at 13:06
  • 1
    Is Hydrargyrum's answer that has +25 votes as of time of writing an answer to the original question, or a comment on someone else's answer?
    – mo.
    Commented May 9, 2013 at 22:28
3

It won't let me comment directly on the incorrect messages - but let me just warn everyone, that the definition of the /XN and /XO options are REVERSED compared to what has been posted in previous messages.

The Exclude Older/Newer files option is consistent with the information displayed in RoboCopy's logging: RoboCopy will iterate through the SOURCE and then report whether each file in the SOURCE is "OLDER" or "NEWER" than the file in the destination.

Consequently, /XO will exclude OLDER SOURCE files (which is intuitive), not "older than the source" as had been claimed here.

If you want to copy only new or changed source files, but avoid replacing more recent destination files, then /XO is the correct option to use.

1
  • Thanks for posting this, now it makes sense. I was thinking about from the perspective of the desired outcome - stop newer files in the destination from being overwritten. But as your comment highlights, I needed to instead reorient my thinking to consider it from Robocopy's perspective which was exclude older files from the copy process so that newer files were not overwritten.
    – mattpm
    Commented May 26, 2022 at 0:30
3
robocopy src dst /MIR /XX

/XX : eXclude "eXtra" files and dirs (present in destination but not source). This will prevent any deletions from the destination. (this is the default)

1

Robocopy can be downloaded here for systems where it is not installed already. (I.e. Windows Server 2003.)

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17657 (no reboot required for installation)

Remember to set your path to the robocopy exe. You do this by right clicking "my computer"> properties>advanced>"Environment Variables", then find the path system variable and add this to the end: ";C:\Program Files\Windows Resource Kits\Tools" or wherever you installed it. Make sure to leave the path variable strings that are already there and just append the addtional path.

once the path is set, you can run the command that belisarius suggests. It works great.

0

This is what has worked for me. I use this to "add" files over to the other drive, with no overwrites.

Batch file: robocopy-missingfiles.bat

@echo off
echo Copying 
echo      "%1"
echo   to "%2"
echo.
echo Press Cntr+C to abort
Pause
echo.
@echo on
robocopy %1 %2 /Xo /XN /XC /J /SL /S /MT:8 /R:1 /W:1 /V /DCOPY:DAT /ETA /COPY:DATO /FFT /A-:SH /XD $RECYCLE.BIN "System Volume Information"

Example:

robocopy-missingfiles.bat f:\Working-folder\ E:\Backup-folder\

Do test before implementation.

0

We can use XCOPY command to copy files from source to destination folder without overriding any existing files in target directory.

First get a list of file names which already existing in destination using xcopy option /L/U/Y and write it in some temporary file say ExcludeFiles.txt.

Then again use XCOPY command with /EXCLUDE: option and provide file path that contain list of file names that need to be excluded. Create a batch file say "Copy-Files.bat" with below content and enjoy! Modify if you want to ask user input for source and destination directory path.

@echo off
set source="C:\Dir1"
set destination="C:\Dir2"

echo Copying non-existing files. NO OVERWRITE!

xcopy %source% %destination% /L/U/Y > %TEMP%\ExcludeFiles.txt
xcopy %source% %destination% /EXCLUDE:%TEMP%\ExcludeFiles.txt
pause
0

If you are trying to put in files without overwriting existing files, you have a few options.

  1. rename those files by, for example, putting "(1)" or "(2)" or something like it after the file name; that way you can distinguish between the two easier.

  2. completely bypass the command line and use Windows Explorer. Unless if you don't have Windows.

That is all I can think of. Hope this helps.

-1

A simple approach would be to use the /MIR option, to mirror the two directories. Basically it will copy only the new files to destination. In next comand replace source and destination with the paths to your folders, the script will search for any file with any extensions.

robocopy <source directory> <destination directory> *.* /MIR

Not the answer you're looking for? Browse other questions tagged or ask your own question.