该任务可以使用带有以下代码的批处理文件来完成:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir "* - *" /A-D /B 2^>nul') do for /F "eol=| delims=-" %%J in ("%%I") do (
if not exist "%%~nxJ" md "%%~nxJ"
if exist "%%~nxJ" move "%%I" "%%~nxJ\"
)
endlocal
命令DIR搜索
- 在当前目录中
- 仅用于文件,因为选项
/A-D(属性不是目录)
- 其中的文件名与通配符模式
* - *匹配
- 并以裸格式输出找到的文件名,因为选项
/B 意味着只有文件名和扩展名而没有路径。
可能找不到符合条件的文件名,这将导致写入错误消息以处理 STDERR。通过将其重定向到设备 NUL 来抑制此可能的错误消息。
阅读有关Using command redirection operators 的Microsoft 文档,了解2>nul 的解释。重定向运算符 > 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令 FOR 之前处理此命令行时解释为文字字符> 在后台启动的单独命令进程中执行嵌入的dir 命令行,cmd.exe /c 和' 中的命令行作为附加参数附加。
DIR在后台命令过程中的输出被FOR捕获并逐行处理。
FOR 使用选项/F 会跳过此处根本不会出现的空行。 FOR 处理捕获的行的默认行为是使用普通空格和水平制表符作为字符串分隔符将行拆分为子字符串,并将第一个空格/制表符分隔的字符串分配给指定的循环变量@987654335 @。 DIR 输出的文件名不需要这种行拆分行为,因为文件名肯定包含空格,并且需要整个文件名来进一步处理文件。出于这个原因,选项delims= 用于定义一个空的字符串分隔符列表以关闭行拆分行为,从而获取分配给循环变量I 的扩展名的文件名。
FOR on using option /F 也将查看第一个子字符串的第一个字符,如果它以分号开头,它是默认的行尾字符,则会忽略该行以进行进一步处理。作者姓名不太可能以; 开头,但仍然可以使用选项eol=| 重新定义行尾字符,并带有竖线,任何文件名都不能包含该竖线。
第二个for /F 用于分割文件名字符串,使用- 作为字符串分隔符,并仅获取分配给指定循环变量J 的第一个子字符串。只要作者姓名不包含-,这适用于您的文件名。所以J在每个文件名上定义为Authors name ,连字符后面的空格作为尾随空格。
有关 Naming Files, Paths, and Namespaces 的 Microsoft 文档解释了 Windows 如何通过删除尾随空格/点来处理文件/文件夹名称。出于这个原因,%%~nxJ 用于引用直到第一个 - 的字符串,根据作者的姓名是否已经存在,独立于子目录中删除了尾随空格和点。
第一个IF条件用于判断作者名字的子目录是否不存在,如果不存在子目录,则使用MD命令创建目录.
第二个IF条件用于验证根据作者姓名的子目录现在是否存在,如果符合预期,则使用命令MOVE移动文件进入子目录。
上面的一个变体是:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir "* - *" /A-D /B 2^>nul') do for /F "eol=| tokens=1* delims=-" %%J in ("%%I") do (
if not exist "%%~nxJ" md "%%~nxJ"
if exist "%%~nxJ" for /F "eol=| tokens=*" %%L in ("%%K") do move "%%I" "%%~nxJ\%%L"
)
endlocal
不同之处在于,每个文件都被移动到具有新名称的子目录中,直到第一个连字符和第一个连字符之后的所有空格都从文件名中删除,以使子目录中的文件在文件名中没有作者姓名。
在不使用环境变量和延迟变量扩展的情况下使用命令行的主要优点是此代码也适用于包含一个或多个感叹号的文件名。
要了解所使用的命令及其工作原理,请打开command prompt 窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
dir /?
echo /?
endlocal /?
for /?
if /?
md /?
move /?
setlocal /?