30

I've seen some scripts examples over SO, but none of them seems to provide examples of how to read filenames from a .txt list.

This example is good, so as to copy all files from A to B folder

xcopy c:\olddir\*.java c:\newdir /D /E /Q /Y

But I need something like the next, where I can fill actually the source and destination folder:

 @echo off
 set src_folder = c:\whatever\*.*
 set dst_folder = c:\foo
 xcopy /S/E/U %src_folder% %dst_folder%

And instead of src_folder = c:\whatever\*.*, those *.* need to be list of files read from a txt file.

File-list.txt (example)

file1.pds
filex.pbd
blah1.xls

Could someone suggest me how to do it?

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
BoDiE2003
  • 1,349
  • 6
  • 28
  • 41
  • 6
    In `bash`, this would be a piece of cake. Darn you Windows and your inability to comply! – Blender Jun 06 '11 at 20:58
  • 1
    This is one of the things batch programming was made for, so it's a piece of cake here, too. – indiv Jun 06 '11 at 21:27
  • how can I add an extension to %%i? on filelist.txt I have the file names, but the files are .pbd extension – BoDiE2003 Jun 07 '11 at 18:39

6 Answers6

52

Given your list of file names in a file called File-list.txt, the following lines should do what you want:

@echo off
set src_folder=c:\whatever
set dst_folder=c:\target
for /f "tokens=*" %%i in (File-list.txt) DO (
    xcopy /S/E "%src_folder%\%%i" "%dst_folder%"
)
Frank Bollack
  • 24,478
  • 5
  • 49
  • 58
  • 3
    to cope with blanks in the filenames in filelist use option `"tokens=*"` in the `FOR` command. – PA. Jun 07 '11 at 06:49
  • It says that It cannot find the files, plus, I dont uderstand where to add "tokens=*" – BoDiE2003 Jun 07 '11 at 18:45
  • for /f "tokens=*" %%i in (File-list.txt) DO xcopy /S/E/U "%src_folder%\%%i" "%dst_folder%" – Carel Apr 03 '13 at 09:49
  • 2
    I was getting file not found with this answer. Got it working with a slight modification: `for /f "tokens=*" %%i in (File-list.txt) DO xcopy "%src_folder%%%i" "%dst_folder%"` – Anthony Mar 12 '14 at 01:22
  • Thanks @Anthony I've edited the answer to fix this problem, by removing the trailing slash from the src_folder (which is equivalent to what you did). – sparrowt Dec 04 '14 at 16:46
  • Perhaps a nice addition, is when you want to copy not a list of files, but a list of folders and their content, this works: `@echo off set src_folder=d:\source\ set dst_folder=d:\target\ set dir_list=d:\copylist.txt if not exist "%dst_folder%" mkdir "%dst_folder%" for /f "delims=" %%f in (%dir_list%) do ( if not exist "%dst_folder%\%%f\" (mkdir "%dst_folder%\%%f\") xcopy "%src_folder%\%%f\*.*" "%dst_folder%\%%f\" )` – Sander Nov 18 '16 at 12:43
  • Remove the /U ! (Copies only files that already exists in destination) you meant /V (Verifies files...) – The One Jan 31 '17 at 15:48
  • What if I have a list containing the location of the files, like "D:\pics\Lam In\IMG_7894.jpg"? – RogUE Feb 26 '17 at 12:33
19

I just tried to use Frank Bollack and sparrowt's answer, but without success because it included a /U switch for xcopy. It's my understanding that /U means that the files will only be copied if they already exist in the destination which wasn't the case for me and doesn't appear to be the case for the original questioner. It may have meant to have been a /V for verify, which would make more sense.

Removing the /U switch fixed the problem.

@echo off
set src_folder=c:\whatever
set dst_folder=c:\target
for /f "tokens=*" %%i in (File-list.txt) DO (
xcopy /S/E "%src_folder%\%%i" "%dst_folder%"
)
Scriptman
  • 201
  • 3
  • 5
  • I ran into the same situation copying JPG files. None copied with the /U switch, but without /U copying was successful. – Evan Apr 04 '17 at 21:57
3

This will do it:

@echo off
set src_folder=c:\batch
set dst_folder=c:\batch\destination
set file_list=c:\batch\file_list.txt

if not exist "%dst_folder%" mkdir "%dst_folder%"

for /f "delims=" %%f in (%file_list%) do (
    xcopy "%src_folder%\%%f" "%dst_folder%\"
)
indiv
  • 17,306
  • 6
  • 61
  • 82
  • 1
    Some caveats (1)`if not exist` only works for files; (2) `"usebackq"` is useless in this syntax, I would rather include `"tokens=*"` to cope with blanks in the filenames; and (3)use `"` surrounding the parameters of `XCOPY` – PA. Jun 07 '11 at 06:47
2

The following will copy files from a list and preserve the directory structure. Useful when you need to compress files which have been changed in a range of Git/SVN commits¹, for example. It will also deal with spaces in the directory/file names, and works with both relative and absolute paths:

(based on this question: How to expand two local variables inside a for loop in a batch file)

@echo off

setlocal enabledelayedexpansion

set "source=input dir"
set "target=output dir"

for /f "tokens=* usebackq" %%A in ("file_list.txt") do (
    set "FILE=%%A"
    set "dest_file_full=%target%\!FILE:%source%=!"
    set "dest_file_filename=%%~nxA"
    call set "dest_file_dir=%%dest_file_full:!dest_file_filename!=%%"
    if not exist "!dest_file_dir!" (
        md "!dest_file_dir!"
    )
    set "source_file_full=%source%\!FILE:%source%=!"
    copy "!source_file_full!" "!dest_file_dir!"
)
pause

Note that if your file list has absolute paths, you must set source as an absolute path as well.


[¹] if using Git, see: Export only modified and added files with folder structure in Git

Marc.2377
  • 7,807
  • 7
  • 51
  • 95
  • 1
    Worked much better than the xcopy solution did for me as it didn't create a ton of empty folders and dump everything in the target folder like the top-voted answer did :| – Merlyn Morgan-Graham Jul 24 '18 at 08:47
1

This will also keep the files original file directory:

@echo off
set src_folder=c:\whatever
set dst_folder=c:\target
set file_list=C:\file_list.txt

for /f "tokens=*" %%i in (%file_list%) DO (
   echo f | xcopy /E /C /R /Y "%src_folder%\%%i" "%dst_folder%\%%i"
)
Norlig
  • 11
  • 3
0

Also can use robocopy and Not use for loop with xcopy - can parse list of files in argument.

robocopy Source_folder Destination_folder [files_to_copy] [options]

Files to copy it's string with Space delimiter. For example:

robocopy . "d:\my folder" *.txt "my file one.cpp" file2.cpp
robocopy "d:\F 15" "d:\backup\F 15" /E
Redee
  • 547
  • 5
  • 8