170

Is there a way to copy directories recursively inside a .bat file? Is an example of this available?

halfer
  • 19,824
  • 17
  • 99
  • 186
sarsnake
  • 26,667
  • 58
  • 180
  • 286
  • 2
    you mean xcopy /s ? or the more advanced robocopy? – rene Nov 09 '12 at 19:14
  • This might help you, although this deletes you can easily change to copy instead http://www.daniweb.com/web-development/threads/61479/recursive-delete-using-a-batch-file-on-windows-xp – Georges Chitiga Nov 09 '12 at 19:15
  • See also http://superuser.com/questions/206036/commmand-line-command-to-copy-entire-directory-including-directory-folder-to-a – anre Mar 01 '17 at 12:30

5 Answers5

219

Look into xcopy, which will recursively copy files and subdirectories.

There are examples, 2/3 down the page. Of particular use is:

To copy all the files and subdirectories (including any empty subdirectories) from drive A to drive B, type:

xcopy a: b: /s /e

Steve Wranovsky
  • 5,503
  • 4
  • 34
  • 52
lc.
  • 113,939
  • 20
  • 158
  • 187
  • 24
    You probably want the /y flag included too to "Suppresses prompting to confirm you want to overwrite an existing destination file." – Matthew Lock Jul 23 '14 at 08:55
  • 12
    'xcopy' is not a good idea because they are notoriously famous for **Insufficient memory error** . Try using 'robocopy' – Rahul Sep 03 '14 at 22:18
  • 6
    @Rahul Hmm really? I've never seen that, but xcopy *has* certainly been around since the dark ages. You could probably do `Copy-Item -Recurse` in PowerShell instead too. – lc. Sep 04 '14 at 14:14
  • 1
    Unfortunately yes, this behaviour is very common :). If have seen this happening recurrently particularly if you wish to copy large amount of data like gigs of data. – Rahul Sep 04 '14 at 16:38
  • 12
    [This](http://ss64.com/nt/xcopy.html) says that xcopy has been deprecated and that robocopy should be used. – Mike H-R Jan 09 '15 at 16:00
  • Also consider adding the `/i` option: "If Source is a directory or contains wildcards and Destination does not exist, xcopy assumes destination specifies a directory name and creates a new directory. Then, xcopy copies all specified files into the new directory. By default, xcopy prompts you to specify whether Destination is a file or a directory." (from [MS online documentation](http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/xcopy.mspx?mfr=true)) – Sue Maurizio Mar 26 '15 at 11:13
  • Just to note that in case that the destination's drive is out of space only some directories/files will be copied without any warning message! – mchar Jan 17 '17 at 14:49
  • Do not forget quotes in path: xcopy /s /e /y "C:\*" "E:\BACKUP\= wow =\*" – Vladimir Sep 13 '18 at 05:06
  • @MikeH-R. The link you reference currently says "In 2007 XCOPY was deprecated in favor of Robocopy, but it has since been given a reprieve and some new features added." – Dr Phil Mar 07 '23 at 20:32
102

After reading the accepted answer's comments, I tried the robocopy command, which worked for me (using the standard command prompt from Windows 7 64 bits SP 1):

robocopy source_dir dest_dir /s /e
Antônio Medeiros
  • 3,068
  • 1
  • 27
  • 22
  • 6
    Never knew 'robocopy' is an inbuilt command in windows 7! Thanks for the answer, very helpful and powerful :) – Anmol Saraf Mar 08 '16 at 01:54
  • 5
    Doesn't `/E` imply `/S`? `copy subdirectories, including Empty ones.` – mbomb007 May 11 '16 at 19:32
  • 6
    Hmmm `/S` and `/E` seem to imply opposite things according to the robocopy `/?` help - s is "not empty ones" e is "empty ones". I think you should just choose one. – Stuart Brock Feb 23 '17 at 18:09
  • 1
    For most users, I think it's sufficient to do /e (include empty directories). – phsource Jun 24 '18 at 23:48
  • 4
    Note that `robocopy` returns an exit code of 1 if one or more files were successfully copied. – dougnorton Mar 18 '19 at 16:08
  • the Robocopy help isn't ambiguous at all with the difference between `/S` and `/E` - `/E` says `copy subdirectories, including Empty ones`. It doesn't say *only* empty ones. – LeeM Aug 30 '19 at 08:50
19

I wanted to replicate Unix/Linux's cp -r as closely as possible. I came up with the following:

xcopy /e /k /h /i srcdir destdir

Flag explanation:

/e Copies directories and subdirectories, including empty ones.
/k Copies attributes. Normal Xcopy will reset read-only attributes.
/h Copies hidden and system files also.
/i If destination does not exist and copying more than one file, assume destination is a directory.


I made the following into a batch file (cpr.bat) so that I didn't have to remember the flags:

xcopy /e /k /h /i %*

Usage: cpr srcdir destdir


You might also want to use the following flags, but I didn't:
/q Quiet. Do not display file names while copying.
/b Copies the Symbolic Link itself versus the target of the link. (requires UAC admin)
/o Copies directory and file ACLs. (requires UAC admin)

Mike Clark
  • 481
  • 3
  • 5
16

You may write a recursive algorithm in Batch that gives you exact control of what you do in every nested subdirectory:

@echo off
call :treeProcess
goto :eof

:treeProcess
rem Do whatever you want here over the files of this subdir, for example:
copy *.* C:\dest\dir
for /D %%d in (*) do (
    cd %%d
    call :treeProcess
    cd ..
)
exit /b

Windows Batch File Looping Through Directories to Process Files?

Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • 6
    Great idea but isn't your program copy all the files from source directories into a single destination directory without preserving the folder hierarchy? – Jean-Francois T. Mar 28 '14 at 04:19
0

Pure batch *.bat snippet for recursive folder with files copy. Without xcopy/robocopy and other external tools
It is loop over directories, concatenate destination path with relative source path and copy folders. Relative path get from the absolute path without source part (cutted by source path length).

Set sourcedir path for the source directory
Set destdir path for the destination directory
(1) rmdir /s /q %destdircopy% will remove all files in the destination folder

For example, this code will remove directory "build\src" and copy all folders with files from "src\" to "build\src"

@ECHO OFF
SET "sourcedir=src"
SET "destdir=build"
SET "destdircopy=%destdir%\%sourcedir%"
@REM (1) ------------------------------------------------------- CLEAR BEFORE COPY
rmdir /s /q %destdircopy%
@REM (2) ------------------------------------------------------- GET SOURCE PATH LENGTH
Setlocal EnableDelayedExpansion
set "files=0"
pushd %sourcedir%
set ABS_PATH=%CD%
popd
echo "%sourcedir% absolute path is %ABS_PATH%"
call :length srclen "%ABS_PATH%"
@REM (3) ------------------------------------------------------- FOR SUBDIRECTORIES LOOP
for /f "tokens=*" %%G in ('dir /b /s /a:d "%sourcedir%"') do (
    set /a files += 1
    call :length len "%%~fG"
    setlocal enabledelayedexpansion
    SET _path=%%~fG
    SET _startchar=%srclen%
    SET  /A _length=!len!-%srclen%
    CALL SET _substring=%%_path:~!_startchar!,!_length!%%
    set currentpath=%%G
    MKDIR %destdircopy%!_substring!
    copy !currentpath! %destdircopy%!_substring!
)
copy %sourcedir% %destdircopy%
goto :EOF
@REM (4) ------------------------------------------------------- PATH STRING LENGTH
:length <return_var> <string>
setlocal enabledelayedexpansion
if "%~2"=="" (set ret=0) else set ret=1
set "tmpstr=%~2"
for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if not "!tmpstr:~%%I,1!"=="" (
        set /a ret += %%I
        set "tmpstr=!tmpstr:~%%I!"
    )
)
endlocal & set "%~1=%ret%"
goto :EOF
@REM (5) www.ildar.in/code/snippets/batch_folder_copy_recurcive.bat
ildarin
  • 31
  • 5