Windows 在文件夹的首字母目录中移动文件夹
我使用此脚本在文件夹的第一个字母目录中移动文件夹Windows 在文件夹的首字母目录中移动文件夹,windows,batch-file,cmd,Windows,Batch File,Cmd,我使用此脚本在文件夹的第一个字母目录中移动文件夹 @echo off setlocal enabledelayedexpansion tree for /d %%i in (*) do ( set first=%%i set first=!first:~0,1! md !first! 2>nul if not "!first!" == "%%i" move "%%i" "!first!\%%i"
@echo off
setlocal enabledelayedexpansion
tree
for /d %%i in (*) do (
set first=%%i
set first=!first:~0,1!
md !first! 2>nul
if not "!first!" == "%%i" move "%%i" "!first!\%%i"
)
tree
首字母目录由该脚本生成。例如,如果我有这样的文件夹名称
Wachenfeldt - The
Пламень - Чужие
Von Stroheim - Lov
此脚本生成的第一个字母目录可以是
W
П
V
如果第一个字母目录在为什么会有问题?脚本部分起作用,因为许多文件夹没有移动到它们自己的第一个字母目录中,并且没有移动到CMD中。我看到了以下错误消息: 文件名或扩展名太长 移动的文件夹名称示例
Wachenfeldt - The Interpreter (2019) Progressive Death Metal
Whitby Bay - Gothic Attack Vehicle (2018) Black Metal
Пламень - Чужие (2017) Black Metal (D5)
W
|
|---- Wachenfeldt - The Interpreter....
|----- Whitby Bay - Gothic Attack....
П
|
|----- Пламень - Чужие (20...
未移动的文件夹名称示例(脚本不适用于它们)
我建议此文件夹移动任务使用以下批处理代码:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
%SystemRoot%\System32\tree.com
for /F "eol=| delims=" %%I in ('dir /AD /B 2^>nul') do (
set "FolderName=%%I"
setlocal EnableDelayedExpansion
set "TargetFolder=!FolderName:~0,1!"
if not "!TargetFolder!" == "!FolderName!" (
md "!TargetFolder!" 2>nul
move /-Y "!FolderName!" "!TargetFolder!\"
)
endlocal
)
%SystemRoot%\System32\tree.com
endlocal
对于将文件夹移动到子文件夹的任务来说,最重要的是首先将文件夹名的整个列表加载到内存中,然后使用for循环处理每个文件夹名。在(*)do中仅使用for/d%%i时,for
命令迭代文件夹名称列表,直接从文件系统按名称获取,该列表会随着循环中每次执行命令而更改,因为可能会创建一个额外的文件夹并将文件夹移动到子文件夹中。这很容易导致一个文件夹被多次处理(这里没有问题),或者在FOR迭代列表时,由于当前文件夹中的文件夹发生了更改而被跳过。特别是在FAT32和exFAT驱动器上,目录项没有按字母顺序按本地特定顺序排序,因此必须首先获取加载到内存中的文件夹的完整列表,然后开始迭代内存中列表中的文件夹,该列表在执行时不受文件系统修改的影响循环中的命令
FORwith option/F
导致在后台启动另一个命令进程,并将%ComSpec%/c
和中的命令行作为附加参数附加。因此在后台执行,Windows安装到C:\Windows
:
C:\Windows\System32\cmd.exe /c dir /AD /B 2>nul
后台命令进程执行的命令DIR在当前目录中搜索
- 仅文件夹,因为选项
/AD
(属性目录),包括具有隐藏属性集的文件夹,该属性集被/D
忽略,并且
/B
,仅以裸格式输出没有路径的文件夹名称/F
默认情况下忽略空行,这在这里没有问题。默认情况下,使用普通空格和水平制表符作为字符串分隔符,将行拆分为子字符串。使用delims=
禁用该行拆分行为,因为文件夹名称可以包含一个或多个空格,因此定义了一个空的分隔符列表。如果第一个子字符串(=本例中的整行)以默认的行尾字符开头,则也将忽略一行这里不需要作为文件夹名称的code>可以以分号开头eol=|
将行尾字符重新定义为一个垂直条,任何文件夹名称都不能包含它,就像?
或*
一样,也可以使用它
在将当前文件夹名称分配给环境变量时未启用,因为文件夹名称包含一个或多个批处理文件无法正确处理代码>。如果在处理此命令行时已启用延迟环境变量扩展,则Windows命令处理器会将文件夹名称中的感叹号解释为命令行上延迟扩展的环境变量引用的开始/结束设置“FolderName=%%I”
另见:
但是,有必要为其他命令启用延迟扩展,如和所述,因此现在使用命令setlocal EnableDelayedExpansion
启用延迟扩展
重要的是在以下命令行中始终引用延迟扩展的环境变量FolderName
,不要使用%%I
来处理带有一个或多个感叹号的正确文件夹名称
如果当前文件夹名称不是一个单字符的文件夹名称,则当前处理的文件夹将移动到其名称为当前文件夹名称第一个字符的子文件夹中,当然,目标文件夹的创建是成功的,并且当前文件夹可以真正移动,因为没有正在运行的进程使用此名称文件夹或其子文件夹之一作为当前文件夹,并且正在运行的进程未打开此文件夹或其子文件夹中的任何文件,只要进程打开且目标文件夹中尚未包含同名文件夹,则会阻止删除或移动该文件
然后,在处理me中列表中的下一个文件夹名称之前,必须还原上一个执行环境
C:\Windows\System32\cmd.exe /c dir /AD /B 2>nul