I need to find a number of 500 image files, of which names I have listed in a text file (a single filename per line). The search is to be done in all subfolders of an external HDD and all files are to be copied to local drive.
pushd D:\move_script
for /f "tokens=* delims=" %%a in ('type List.txt') do xcopy /hrkvy ".\SourceFolder\%%a" ".\DestinationFolder"
popd
Files not found in SourceFolder.There are multiple subfolders in directory D:\move_script So how i mentioned the sourcefolder so that it can search files in all subfolders under D:\move_script .
When i use the single sourcefolder like in the below command then its searched files only under data folder and copied to destination folder.
for /f "tokens=* delims=" %%a in ('type List.txt') do xcopy /hrkvy ".\**data**\%%a" ".\DestinationFolder"
Please help what is wrong for search source subfolders.
AIUI, the problem is to copy the files named in the list.txt
file from wherever they exist in the source subtree to the destination directory.
An issue with your code: You have used a pushd/popd
bracket, which means that between the pushd
and the popd
, the current directory is (the argument to the PUSHD
)
The .
in the term ".\SourceFolder\%%a"
means the directory relative to the current directory - and the current directory is D:\move_script
, so the source interpreted by xcopy
is "D:\move_script\SourceFolder\%%a"
The easy way to fix this is to remove the pushd/popd
commands, and execute
D:\move_script\thisbatchname
which will execute the remaining command relative to the directory selected at the time of execution.
There is a problem with the approach. Given that the xcopy
could be fixed to perform the copy of the one file in the source subtree that matches the name in %%a
, that search would need to be done 500 times - once for each entry in list.txt
, which would be v.e.r.y. .s.l.o.w.
So here's another approach:
@ECHO OFF
SETLOCAL
rem The following settings for the directory and filename are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q78088112.txt"
(
FOR /f "delims=" %%e IN ('XCOPY /L /Y /S "%sourcedir%\*"') DO ECHO %%e^|%%~nxe
)>"%temp%\####.exist"
(
FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO ECHO ^|%%e
)>"%temp%\####.incl"
FOR /f "tokens=1delims=|" %%e IN ('findstr /e /L /g:"%temp%\####.incl" "%temp%\####.exist"') DO ECHO COPY "%%e" "destdirname"
DEL "%temp%\####.excl" "%temp%\####.exist"
GOTO :eof
Note that if the filename does not contain separators like spaces, then both usebackq
and the quotes around %filename1%
can be omitted.
The required COPY commands are merely ECHO
ed for testing purposes. After you've verified that the commands are correct, change ECHO COPY
to COPY
to actually copy the files. Append >nul
to suppress report messages (eg. 1 file copied
)
First, perform an xcopy
listing, creating a full filelist in a temporary file ####.exist
with each line of the format fullfilename|filenameandextension
Next, process the filename list to ####.incl
, simply inserting a |
before each filename
Then find the first token of the lines in ####.exist
using |
as a delimiter (which becomes the full filename of the file to be copied) WHERE the line /e
ends with any entry in the /g:
file, ####.incl
Note that |
cannot appear in a legitimate filename.