There are several problems:
- Since you are trying to move directories, the directory tree enumerated by
for /R is modified. for/for /R however does not enumerate the directory (tree) in advance, therefore unexpected results may occur -- see the following question for details about that: At which point does for or for /R enumerate the directory (tree)?.
for or for /R accesses the file system only in case there are wildcards given in the set (that is the part in between parentheses).
- It is not perfectly clear what exactly you want to accomplish:
- what should happen in case of conflicting items? overwrite them or not? merge (sub-)directories?
- in case of
E:\TEST\TEST, do you want E:\TEST to be moved at once, so there is no more directory TEST at E:\?.
- Note that the
move command cannot be used because it causes trouble when moving directories and the destination directory already exists (Access is denied. errors occur).
Item 1. can be solved by a nice work-around using for /F and dir:
for /F "eol=| delims=" %%I in ('dir /B /S /A:D "E:\TEST"') do echo(%%I
This enforces the entire directory tree to be enumerated (read) before the loop iterations start.
However, this introduces another problem similar to item 2.: when a name is given for dir that matches a directory existing in the given location, its content is returned rather than all items matching that name. What I mean is the following:
dir /B /S /A:D "E:\" returns all directories (/A:D) at E:\ recursively (/S);
dir /B /S /A:D "E:\file.ext" returns all directories called file.ext, even if there is a file named E:\file.ext;
- but:
dir /B /S /A:D "E:\TEST" returns all sub-directories of E:\TEST, but not E:\TEST itself;
- however:
dir /B /S /A:D "E:\TEST*" returns all directories beginning with TEST, also those in E:\; to exactly match the name TEST, additional filtering is required (using findstr);
All this means:
for /F "eol=| delims=" %%I in ('dir /B /S /A:D "E:\TEST*" ^| findstr /I /E /C:"\\TEST"') do echo(%%I
Item 3. can only be solved by you, but to provide a complete answer, I make some assumptions:
- (sub-)directories are merged, already existing items are overwritten without notice;
- parent directories take precedence over sub-directories (like
for /R and dir /S behave, because for every branch in a tree, they always go from higher down to lower directory levels);
Item 4. can be solved by using command robocopy together with option /MOVE instead of move.
So here is the final script:
@echo off
rem // Define constants here:
set "_PATH=E:\"
set "_NAME=TEST"
set "_DEST=E:\FOUND"
2> nul mkdir "%_DEST%"
for /F "eol=| delims=" %%I in ('
dir /B /S /A:D "%_PATH%\%_NAME%*" ^| findstr /I /E /C:"\\%_NAME%"
') do (
> nul robocopy "%%I" "%_FOUND%\%_NAME" /E /MOVE
)
The > nul portion is intended to suppress progress and log messages and to suppress The system cannot find the path specified. errors in case E:\TEST\TEST is attempted to be moved although it does no longer exist since the parent E:\TEST has alread been moved before.