Recursive move folders in windows, .bat archive

Viewed 108

We have a folder structure like this

dir 1
  - dir A
  - dir B
dir 2
  - dir C
dir 3
dir 4

Need to move to other directory, all dirs and subdirs, to same level, like this

d:\basedir
    dir 1
    dir A
    dir B
    dir 2
    dir C
    dir 3
...

I¡ve tried this script but, doesn't works

 for %%x in (%*) do (
    move %%x d:\basedir\
)
3 Answers

The difficulty with the standard methods to solve this type of problems is that they works top-to-bottom, that is, they process first the top-most level folder. To correctly solve this problem the folders must be processed bottom-to-top: process first the last folders in the tree.

You may use the recursive process of a directory tree described at this answer

@echo off
cd D:\data\folder
call :treeProcess
goto :eof

:treeProcess
for /D %%d in (*) do (
   cd "%%d"
   call :treeProcess
   cd ..
   move "%%d" D:\basedir
)
exit /b

Or, in a simpler way:

@echo off
cd D:\data\folder

:treeProcess
for /D %%d in (*) do (
   cd "%%d"
   call :treeProcess
   cd ..
   move "%%d" D:\basedir
)

When you move a directory, its sub-directories are no longer available at the source location, so you need to first handle sub-directories before you move their parents:

rem /* Iterate through all directories in the tree, and change the default
rem    top-to-bottom order to bottom-to-top order per each sub-branch: */
for /F "delims= eol=|" %%I in ('
    dir /S /B /A:D-H-S "D:\source\*" ^| sort /R
') do (
    move "%%~I" "D:\basedir\"
)

If you just want the sub- and sub-sub-directories to be moved but not deeper ones, use this code instead:

rem // Iterate through immediate child directories:
for /D %%J in ("D:\source\*") do (
    rem // Iterate through grandchild directories:
    for /D %%I in ("%%~J\*") do (
        rem // Move current grandchild directory:
        move "%%~I" "D:\basedir\"
    )
    rem // Move current child directory:
    move "%%~J" "D:\basedir\"
)

FOR /D should do what you need.

Consider this example:

SET "SOURCE_DIR=n:\path\to\data"
FOR /D %%d IN (%SOURCE_DIR%\*.*) DO (
    @ECHO %%~fd
)

It returns the absolute path to all the directories underneath SOURCE_DIR.

Related