Here's my analysis of your code:
for /f "delims=" %%A in ('dir /b %PATH1%') do (
rem %%A contains filename + extension of each file AND DIRECTORY in path1
dir /s /b /r %PATH2% | find /i "%%A" > list.txt
rem LIST.txt contains full pathnames of all filenames AND DIRECTORIES
rem where "%%A" forms part of the full pathname
SET /p PATH3<=list.txt
rem PATH3 contains the first line of list.txt
move %PATH1%%%A %PATH3%
rem move `path1%%A` (a file or directoryname - but without the `\` separator)
rem to the first (probably filename) found
)
Comment : first time in using batch for the last 40 years that I've ever seen the /r
swich used in a dir
statement...
So - we have to make some reasonable assumptions as to the intent of this code.
Tip: Use set "var=value"
for setting string values - this avoids problems caused by trailing spaces. Don't assign "
or a terminal backslash or Space. Build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value"
is used, then the quotes become part of the value assigned.
@echo off
SET "PATH1=FIND_PATH"
SET "PATH2=OVERWRITE_PATH"
for /f "delims=" %%b in ('dir /b /a-d "%PATH1%"') do (
for /f "delims=" %%u in ('dir /s /b /a-d /r "%PATH2%\%%b" 2^>nul') do (
ECHO move "%PATH1%\%%A" "%%u"
)
)
[1] Change to better set
syntax
[2] Prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) as ADFNPSTXZ are metavariable-modifiers which can lead to difficult-to-find bugs (See for/f
from the prompt for documentation)
[3] Include /a-d
to exclude directory names from dir
lists
[4] Include %%b
in the filemask for the inner for
to search for that exact name only in the destination directory-tree
[5] The 2^>nul
suppresses an error message should no files be found in the destination-tree matching the filename. The caret (^
) is required to tell cmd
that the >
is part of the dir
command, not the for
[6] Append the filename found (%%b
) to the source directoryname with required separator
[7] %%u
will contain the full pathnames of the matching files in the destination directory-tree
[8] The resultant command is merely echo
ed for verification. After verification, remove the echo
keyword to actually execute the move
.
Untested
Always verify against a test directory before applying to real data.
The effect would be to find all of the filenames in the source directory and move
it over all matching filenames in the destination directory tree.
LOGICAL FLAW
a "move" command would move a file a.txt
over the first a.txt
in the destination-tree. Then the source file no longer exists (as it's been moved) so if a second a.txt
is located in the destination-tree, then the move
will fail.
Consider this further modification:
@echo off
SET "PATH1=FIND_PATH"
SET "PATH2=OVERWRITE_PATH"
for /f "delims=" %%b in ('dir /b /a-d "%PATH1%"') do (
set "moved="
for /f "delims=" %%u in ('dir /s /b /a-d /r "%PATH2%\%%b" 2^>nul') do (
set "moved=y"
ECHO COPY "%PATH1%\%%A" "%%u"
)
if defined moved (
ECHO del "%PATH1%\%%A"
) else (
ECHO "%PATH1%\%%A" - no matches in tree "%PATH2%" found
ECHO MOVE "%PATH1%\%%A" "%PATH2%"
)
)
This change sets moved
to nothing for each source file found, then sets it to y
if any matching filename is found n the destination tree.
If the file has been copied, then delete the source file, otherwise complain and move it to the destination-tree-root.