Bat file to copy Folders and Files
When the source is a directory, the xcopy
command copies its contents rather than the whole directory. To copy the whole directory, you need to alter the destination accordingly:
xcopy /I /Y /S "%src_folder%\%%f" "%dst_folder%\%%f"
Note the /I
option, that tells xcopy
that the destination is not a file but a directory.
However, when the source is a single file, xcopy
prompts you whether the destination is a file or directory when the destination does not yet exist, even when /I
is provided (refer to this related post). Therefore, we have to determine what the source (%%f
) is in advance and react adequately:
@echo off
rem // The quoted `set` syntax protects special characters:
set "src_folder=C:\Users\P57949\Desktop"
set "dst_folder=C:\Users\P57949\Desktop\NewTestFolder"
set "file_list=C:\Users\P57949\Desktop\Filelist.txt"
rem // Append `\*` to check a directory but not a file for existence:
if not exist "%dst_folder%\*" mkdir "%dst_folder%"
rem // Use `usebackq` option and quotation to permit spaces in file path:
for /F "usebackq delims=" %%f in ("%File_list%") do (
rem // Check whether source is a directory:
if exist "%src_folder%\%%f\*" (
rem // Source is a directory, so copy it entirely:
xcopy /I /Y /S "%src_folder%\%%f" "%dst_folder%\%%f"
) else (
rem // Source is a file, or it does not exist:
xcopy /Y /S "%src_folder%\%%f" "%dst_folder%\"
)
)
A bit simpler and more compact approach can be achieved when a destination file is pre-created, so the file/directory prompt does not appear:
@echo off
rem // The quoted `set` syntax protects special characters:
set "src_folder=C:\Users\P57949\Desktop"
set "dst_folder=C:\Users\P57949\Desktop\NewTestFolder"
set "file_list=C:\Users\P57949\Desktop\Filelist.txt"
rem // Append `\*` to check a directory but not a file for existence:
if not exist "%dst_folder%\*" mkdir "%dst_folder%"
rem // Use `usebackq` option and quotation to permit spaces in file path:
for /F "usebackq delims=" %%f in ("%File_list%") do (
rem // Pre-create destination file when source is a file:
if not exist "%src_folder%\%%f\*" > "%dst_folder%\%%f" rem/
rem // No prompt appears even when source is a file:
xcopy /I /Y /S "%src_folder%\%%f" "%dst_folder%\%%f"
)
The easiest approach is to use the /I
option to cover the case when source is a directory and to auto-fill the file/directory prompt for the case source is a file, but this is locale-dependent (for instance, F
ile and D
irectory for English systems, but D
atei and V
erzeichnis for German ones), so be careful:
@echo off
rem // The quoted `set` syntax protects special characters:
set "src_folder=C:\Users\P57949\Desktop"
set "dst_folder=C:\Users\P57949\Desktop\NewTestFolder"
set "file_list=C:\Users\P57949\Desktop\Filelist.txt"
rem // Append `\*` to check a directory but not a file for existence:
if not exist "%dst_folder%\*" mkdir "%dst_folder%"
rem // Use `usebackq` option and quotation to permit spaces in file path:
for /F "usebackq delims=" %%f in ("%File_list%") do (
rem // The `/I` option copes for directories, `echo F` for files:
rem echo F| xcopy /I /Y /S "%src_folder%\%%f" "%dst_folder%\%%f"
)
N. B.:
For all of the above, I assumed that the list file Filelist.txt
contains pure file/directory names.