Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 在文件夹的首字母目录中移动文件夹_Windows_Batch File_Cmd - Fatal编程技术网

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
    ,仅以裸格式输出没有路径的文件夹名称
  • 阅读有关的Microsoft文档,以了解有关nul的说明。当Windows命令解释器在执行FOR的命令之前处理此命令行时,重定向操作符
    必须在上用插入符号^转义,以便命令行被解释为文字字符,该命令行以单独的方式执行嵌入的dir命令行命令进程在后台启动

    为处理已启动命令进程的STDOUT而写入的输出由正在处理批处理文件的命令进程捕获,并在已启动命令进程在执行完命令DIR后自行终止后,由逐行解释

    FOR带有选项
    /F
    默认情况下忽略空行,这在这里没有问题。默认情况下,使用普通空格和水平制表符作为字符串分隔符,将行拆分为子字符串。使用
    delims=
    禁用该行拆分行为,因为文件夹名称可以包含一个或多个空格,因此定义了一个空的分隔符列表。如果第一个子字符串(=本例中的整行)以默认的行尾字符
    开头,则也将忽略一行可以以分号开头
    eol=|
    将行尾字符重新定义为一个垂直条,任何文件夹名称都不能包含它,就像
    *
    一样,也可以使用它

    在将当前文件夹名称分配给环境变量时未启用,因为文件夹名称包含一个或多个
    。如果在处理此命令行时已启用延迟环境变量扩展,则Windows命令处理器会将文件夹名称中的感叹号解释为命令行上延迟扩展的环境变量引用的开始/结束
    设置“FolderName=%%I”

    另见:

    但是,有必要为其他命令启用延迟扩展,如和所述,因此现在使用命令
    setlocal EnableDelayedExpansion
    启用延迟扩展

    重要的是在以下命令行中始终引用延迟扩展的环境变量
    FolderName
    ,不要使用
    %%I
    来处理带有一个或多个感叹号的正确文件夹名称

    如果当前文件夹名称不是一个单字符的文件夹名称,则当前处理的文件夹将移动到其名称为当前文件夹名称第一个字符的子文件夹中,当然,目标文件夹的创建是成功的,并且当前文件夹可以真正移动,因为没有正在运行的进程使用此名称文件夹或其子文件夹之一作为当前文件夹,并且正在运行的进程未打开此文件夹或其子文件夹中的任何文件,只要进程打开且目标文件夹中尚未包含同名文件夹,则会阻止删除或移动该文件

    然后,在处理me中列表中的下一个文件夹名称之前,必须还原上一个执行环境
    C:\Windows\System32\cmd.exe /c dir /AD /B 2>nul