0

I want to create a script that searches a multiple directory "eg: TEST" and move it to a specific location in a folder. I have tried using the below script. It display the folder location example:

"E:\Example\TEST"
"E:\TEST\TEST"

Please check the script i have created. Can anyone help?

@echo off

set filename=TEST

set searchPath=E:\

set Destination= E:\FOUND

FOR /R "%searchPath%" %%a  in (%filename%) DO (
    IF EXIST "%%~fa" (
        echo "%%~fa"
    )
)

move "%%~fa" "%Destination%"
123
  • 10,778
  • 2
  • 22
  • 45
SrK
  • 29
  • 3
  • 9
  • 1
    `for`/`for /R` accesses the file system only in case wild-cards are present in the part/set within `()`; and `for`/`for /R` enumerates files unless you provide the `/D` switch... – aschipfl Dec 02 '16 at 11:26
  • 1
    Remove the space after `=` equals in `set` command. Moreover, use `set "Destination=E:\FOUND"` to ensure that there is no unwanted trailing space . – JosefZ Dec 02 '16 at 12:20

1 Answers1

0

There are several problems:

  1. 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)?.
  2. 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).
  3. 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:\?.
  4. 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.

Community
  • 1
  • 1
aschipfl
  • 33,626
  • 12
  • 54
  • 99