@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:: First, create a list of subdirectorynames; iterate using `%%a`
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" '
) DO (
REM clear initial flags for each dir
SET "flag1="
SET "flag2="
REM Now read the subdirectory. set flag1 for first file, flag2 for second or later
FOR /f %%g IN (
'dir /b /a-d "%sourcedir%\%%a\*" 2^>nul'
) DO IF DEFINED flag1 (SET flag2=y) ELSE (SET flag1=y)
REM if neither flag set, directory is empty
REM if both are set, dir has 2 or more files
REM so - if flag1 but not flag2 is set then exactly 1 file.
IF DEFINED flag1 IF NOT DEFINED flag2 ECHO(MOVE "%sourcedir%\%%a\*" "%sourcedir%\"
REM if flag2 is not set, subdirectory is now empty
IF NOT DEFINED flag2 ECHO(rd "%sourcedir%\%%a"
)
GOTO :EOF
您需要更改sourcedir 的设置以适应您的情况。
所需的 MOVE 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(MOVE 更改为MOVE 以实际移动文件。附加>nul 以禁止报告消息(例如1 file moved)
所需的 RD 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(RD更改为RD以实际创建目录。
我建议您将批处理定位在包含三个子目录的树上,其中包含 0,1 和 2 个用于测试的文件。
由于多种原因,您的批次失败。
- 批处理文件中的元变量(循环控制变量)在每个引用中都需要 double
%
- 环境变量由
%var% 引用,而不是%var。
- 在一个块语句(括号内的一系列语句)中,
%var% 将引用var 的值在最初遇到块时,而不是随着变量在环形。这是delayed expansion 问题 - 此处有详细记录。
请注意,此批处理不会检查目标目录中是否已存在要移动的候选对象。如果是这样,那么move 和rd 语句将生成错误报告,并且文件和目录将保持原样。
注意:不要将任何rem 行更改为:: 表单,因为:: 实际上是终止块的损坏标签(即会导致问题)
编辑 - 修订
@ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir"
:: First, create a list of subdirectorynames; iterate using `%%a`
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" '
) DO (
REM clear initial flags for each dir
ECHO %%a
SET "subdir=%%a"
SET "flag1="
SET "flag2="
REM Now read the subdirectory. set flag1 for first file, flag2 for second or later
FOR /f "delims=" %%g IN (
'dir /b "%sourcedir%\%%a\*" 2^>nul'
) DO SET "name=%%g"&IF DEFINED flag1 (SET flag2=y) ELSE (SET flag1=y)
REM if neither flag set, directory is empty
REM if both are set, dir has 2 or more files/dirs
REM so - if flag1 but not flag2 is set then exactly 1 file/dir
IF DEFINED flag1 IF NOT DEFINED flag2 CALL :moveit
REM if flag2 is not set, subdirectory is now empty
IF NOT DEFINED flag2 rd "%sourcedir%\%%a"
)
GOTO :EOF
:moveit
REM NAME may be a file or a directory - "%sourcedir%\%%a\%NAME%\.." exists if directory
IF NOT EXIST "%sourcedir%\%subdir%\%NAME%\.." MOVE "%sourcedir%\%subdir%\*" "%sourcedir%\"
IF EXIST "%sourcedir%\%subdir%\%NAME%\.." IF NOT EXIST "%sourcedir%\%name%" MOVE "%sourcedir%\%subdir%\%NAME%" "%sourcedir%\"
GOTO :EOF
小心!上述批次 NOT 使用 ECHO( 因此它将尝试
移动或删除文件或目录。仅在测试子树上使用!
此次要修订将单个目录以及单个文件向上移动到目标下方级别的目录中。
如果无法按指示移动或删除,它会显示足够的信息来推断错误消息的来源。
本质上,它与原来的相同,只是调用了一个子例程来进行更改。该子例程使用name 作为它希望移动的目录名,使用subdir 作为正在处理的子目录。