Batch file to copy directories recursively
Asked Answered
M

5

172

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

Maharanee answered 9/11, 2012 at 19:12 Comment(3)
you mean xcopy /s ? or the more advanced robocopy?Assignable
This might help you, although this deletes you can easily change to copy instead daniweb.com/web-development/threads/61479/…Milkwhite
See also superuser.com/questions/206036/…Kosciusko
G
221

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

Graffito answered 9/11, 2012 at 19:13 Comment(9)
You probably want the /y flag included too to "Suppresses prompting to confirm you want to overwrite an existing destination file."Lodicule
'xcopy' is not a good idea because they are notoriously famous for Insufficient memory error . Try using 'robocopy'Parliamentarianism
@Parliamentarianism 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.Graffito
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.Parliamentarianism
This says that xcopy has been deprecated and that robocopy should be used.Grandioso
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)Cockboat
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!Injurious
Do not forget quotes in path: xcopy /s /e /y "C:*" "E:\BACKUP\= wow =*"Mordvin
@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."Alpheus
D
104

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
Dutchman answered 23/6, 2015 at 23:9 Comment(6)
Never knew 'robocopy' is an inbuilt command in windows 7! Thanks for the answer, very helpful and powerful :)Cockrell
Doesn't /E imply /S? copy subdirectories, including Empty ones.Berkly
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.Barela
For most users, I think it's sufficient to do /e (include empty directories).Helices
Note that robocopy returns an exit code of 1 if one or more files were successfully copied.Deledda
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.Mummer
A
22

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)

Aardwolf answered 13/11, 2020 at 17:49 Comment(0)
V
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?

Vacation answered 9/11, 2012 at 21:14 Comment(1)
Great idea but isn't your program copy all the files from source directories into a single destination directory without preserving the folder hierarchy?Francenefrances
P
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
Perce answered 23/7, 2023 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.