Aqui está um script em lote do Windows para isso.
Esse primeiro script moverá os arquivos somente dentro da estrutura de diretórios, semelhante à mostrada na pergunta do OP.
Edite o valor da variável de script "topfolder" para conter a "pasta base" para a estrutura de diretórios.
Edite o valor da variável de script "subfolderprefix" para conter o prefixo comum para as pastas "primeiro nível" a serem pesquisadas em "topfolder". Na pergunta do OP, esse "prefixo" era "pasta", mas pode ser alterado para qualquer string, se necessário. Usando "pasta" como prefixo, por exemplo, o script procurará pastas como esta:
top_folder
folder1
folder2
folder3
folder99
folderABC
mas, outras pastas na pasta "top_folder" serão ignoradas, como estas:
top_folder
somefolder
someotherfolder
As subpastas de "segundo nível" que serão pesquisadas pelos arquivos terão um prefixo comum do nome da pasta pai seguido por "_" ( folder1\folder1_xxx
). Novamente, qualquer outra pasta será ignorada:
top_folder
folder1
folder1_2
(Files here will be moved to "folder1")
folder1_99
(Files here will be moved to "folder1")
folder1_ABC
(Files here will be moved to "folder1")
folder2
folder2_2
(Files here will be moved to "folder2")
somesubfolder
(Files here will be skipped)
folder3
folder3_1
(Files here will be moved to "folder3")
folder3_2
(Files here will be moved to "folder3")
folder99
folder99_XYZ
(Files here will be moved to "folder99")
folderABC
folderABC_123
(Files here will be moved to "folderABC")
somefolder
(Folders here will be skipped)
someotherfolder
(Folders here will be skipped)
Aqui está o script em lote:
@echo off
set "topfolder=C:\Temp\SU373589\top_folder"
set "subfolderprefix=folder"
set "startdir=%CD%"
cd /d "%topfolder%"
set ctoptest=0
set cfilecount=0
for /d %%f in ("%subfolderprefix%*") do call :worklevel1 "%%~f"
if %ctoptest% EQU 0 echo There are no matching subfolders in "%topfolder%".
if %cfilecount% EQU 0 echo There were no files moved.
if %cfilecount% EQU 1 echo %cfilecount% file was moved.
if %cfilecount% GEQ 2 echo %cfilecount% files were moved.
cd /d "%startdir%"
goto :EOF
:worklevel1
set "subfolder=%~1"
set /a ctoptest+=1
echo Processing subfolder "%subfolder%" ...
set "subsubfolderprefix=%subfolder%\%subfolder%_"
set cwork1test=0
for /d %%g in ("%subsubfolderprefix%*") do call :worklevel2 "%%~g"
if %cwork1test% EQU 0 echo There are no matching subfolders in "%subfolder%"
echo.
set "subfolder="
set "subsubfolderprefix="
set cwork1test=
goto :EOF
:worklevel2
set "subsubfolder=%~1"
set /a cwork1test+=1
echo Processing subsubfolder "%subsubfolder%" ...
set cwork2test=0
for %%h in ("%subsubfolder%\*") do call :workmove "%%~h"
if %cwork2test% EQU 0 echo There are no files to move in "%subsubfolder%"
set "subsubfolder="
set cwork2test=
goto :EOF
:workmove
set "targetfile=%~1"
set /a cwork2test+=1
set /a cfilecount+=1
echo Moving file "%targetfile%" to "%subfolder%" (%cwork2test%)...
move "%targetfile%" "%subfolder%" >nul 2>&1
set "targetfile="
goto :EOF
Esse segundo script em lote funcionará de maneira semelhante, procurando em TODAS as subpastas de "primeiro nível" e movendo todos os arquivos de todas as subpastas de "segundo nível" para as subpastas de "primeiro nível". Ele não procurará corresponder a nenhum "prefixo" para nenhum dos nomes de pastas.
Edite o valor da variável de script "topfolder" para conter a pasta base da estrutura de diretórios.
@echo off
set "topfolder=C:\Temp\SE373589\top_folder"
set "startdir=%CD%"
cd /d "%topfolder%"
set ctoptest=0
set cfilecount=0
for /d %%f in ("*") do call :worklevel1 "%%~f"
if %ctoptest% EQU 0 echo There are no matching subfolders in "%topfolder%".
if %cfilecount% EQU 0 echo There were no files moved.
if %cfilecount% EQU 1 echo %cfilecount% file was moved.
if %cfilecount% GEQ 2 echo %cfilecount% files were moved.
cd /d "%startdir%"
goto :EOF
:worklevel1
set "subfolder=%~1"
set /a ctoptest+=1
echo Processing subfolder "%subfolder%" ...
set cwork1test=0
for /d %%g in ("%subfolder%\*") do call :worklevel2 "%%~g"
if %cwork1test% EQU 0 echo There are no matching subfolders in "%subfolder%"
echo.
set "subfolder="
set cwork1test=
goto :EOF
:worklevel2
set "subsubfolder=%~1"
set /a cwork1test+=1
echo Processing subsubfolder "%subsubfolder%" ...
set cwork2test=0
for %%h in ("%subsubfolder%\*") do call :workmove "%%~h"
if %cwork2test% EQU 0 echo There are no files to move in "%subsubfolder%"
set "subsubfolder="
set cwork2test=
goto :EOF
:workmove
set "targetfile=%~1"
set /a cwork2test+=1
set /a cfilecount+=1
echo Moving file "%targetfile%" to "%subfolder%" (%cwork2test%)...
move "%targetfile%" "%subfolder%" >nul 2>&1
set "targetfile="
goto :EOF
Uma versão mais simples do script em lote, sem toda a verificação de pastas vazias, etc ...:
@echo off
set "topfolder=C:\Temp\SE373589\top_folder"
set "startdir=%CD%"
cd /d "%topfolder%"
for /d %%f in (*) do (
echo Processing folder: "%%~f"
for /d %%g in ("%%f\*") do (
echo Processing sub-folder: "%%~g"
for %%h in ("%%~g\*") do (
echo Moving file: "%%~h" to "%%~f"
move "%%~h" "%%~f" >nul 2>&1
)
)
echo.
)
cd /d "%startdir%"
E, finalmente, um script "mínimo" sem mensagens e supondo que você já esteja na "pasta base" adequada:
@echo off
for /d %%f in (*) do (
for /d %%g in ("%%f\*") do (
for %%h in ("%%~g\*") do move "%%~h" "%%~f" >nul 2>&1
)
)
E, caso você espere, um "one liner" pode ser executado a partir do prompt de comando:
@for /d %f in (*) do @(for /d %g in ("%f\*") do @(for %h in ("%~g\*") do @move "%~h" "%~f" >nul 2>&1))