批处理文件 - 递归检查文件夹并移动文件

时间:2014-01-11 19:15:44

标签: batch-file

我正在尝试创建一个Windows批处理文件,该文件将扫描包含许多子文件夹的文件夹。每个子文件夹可以包含许多文件。我需要脚本来检查子文件夹是否包含超过一定数量的文件,以及它是否确实将一半文件移动到具有相同名称但最后带有数字的新文件夹。

示例:

Main folder
-Subfolderone
-Subfoldertwo
-Subfolderthree

如果Subfoldertwo包含超过一定数量的文件,假设为1000,那么Subfoldertwo中的一半文件将被移动到Subfoldertwo(2),依此类推每个子文件夹。

Main folder
-Subfolderone
-Subfoldertwo
-Subfoldertwo(2)
-Subfolderthree

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:5)

@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET limit=5
FOR /f "delims=" %%a IN ('dir /b /s /ad "%sourcedir%\*"') DO (
 SET /a newnum=2
 FOR /f %%c IN ('dir /b/a-d "%%~a" 2^>nul ^|find /c /v ""') DO IF %%c gtr %limit% CALL :process "%%a"
)
)

GOTO :EOF

:process
IF EXIST "%~1(%newnum%)\" SET /a newnum+=1&GOTO process
ECHO MD "%~1(%newnum%)"
FOR /f "skip=%limit%delims=" %%m IN ('dir /b /a-d "%~1"') DO ECHO MOVE "%~1\%%m" "%~1(%newnum%)\"

GOTO :eof

足够简单。我已经将sourcedir设置为我的测试常量,并将限制设置为5,原因相同。

首先构建原始指令树的列表,然后计算每个目录中的文件。如果该计数大于限制,则处理目录。

在进行中,首先查找建议的新目录是否已存在。如果是这样,请继续增加数字,直到它没有。

然后从原始的完整目录名列出文件名(仅),跳过第一个%limit%,其余的,将它们移动到新的目录名。

所需命令仅用于ECHO以用于测试目的。在确认命令正确后,将ECHO MD更改为MD以实际创建目录。附加2>nul以禁止错误消息(例如,当目录已存在时)

并将ECHO MOVE更改为MOVE以实际移动文件。附加>nul以取消报告消息(例如1 file moved


编辑:修改为“移动一半文件”

@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET limit=5
FOR /f "delims=" %%a IN ('dir /b /s /ad "%sourcedir%\*"') DO (
 SET /a newnum=2
 FOR /f %%c IN ('dir /b/a-d "%%~a" 2^>nul ^|find /c /v ""') DO IF %%c gtr %limit% SET /a nmove=%%c / 2&CALL :process "%%a"
)
)

GOTO :EOF

:process
IF EXIST "%~1(%newnum%)\" SET /a newnum+=1&GOTO process
ECHO MD "%~1(%newnum%)"
FOR /f "skip=%nmove%delims=" %%m IN ('dir /b /a-d "%~1"') DO ECHO MOVE "%~1\%%m" "%~1(%newnum%)\"

GOTO :eof

(只需将计数的一半计算到nmove然后跳过该数字)

答案 1 :(得分:3)

你可以测试一下:

@ECHO OFF &SETLOCAL
set "StartFolder=X:\Main folder"
set /a MaxFiles=1000
cd /d "%StartFolder%"
:NewFolderCreated
set "NewFolderFlag="
for /f "delims=" %%a in ('dir /b /ad /on') do call:process "%StartFolder%\%%~a"
if defined NewFolderFlag (goto:NewFolderCreated) else goto:eof

:process
SETLOCAL
cd "%~1"
for /f %%b in ('dir /b /a-d 2^>nul^|find /c /v ""') do set /a FileCount=%%b
if %FileCount% leq %MaxFiles% exit /b
set /a MoveCount=FileCount-MaxFiles
set "CurrentFolder=%~n1"
set "NextPath=%StartFolder%\%CurrentFolder%(2)%~X1"
echo("%CurrentFolder%"|findstr /re ".*([0-9][0-9]*)\"^">nul||goto:moving
set "BasePath=%CurrentFolder:~0,-1%"
:loop
if not "%BasePath:~-1%"=="(" set "FolderNo=%BasePath:~-1%%FolderNo%"&set "BasePath=%BasePath:~0,-1%"&goto:loop
set /a FolderNo+=1
set "NextPath=%StartFolder%\%BasePath%%FolderNo%)%~X1"
:moving
echo(Moving %MoveCount% files from "%~1" to "%NextPath%".
md "%NextPath%" 2>nul &&set "NewFolderFlag=true"
for /f "skip=%MaxFiles%delims=" %%b in ('dir /b /a-d /o-n') do move "%~1\%%~b" "%NextPath%" >nul
endlocal &set "NewFolderFlag=%NewFolderFlag%"
exit /b