我建议将此批处理文件用于文件移动任务。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%I in ('dir "C:\Temp\*.jpg" /A-D /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /C:"\\pre\\" /C:"\\post\\"') do (
if not exist "%%~dpIpre\" md "%%~dpIpre"
move /Y "%%I" "%%~dpIpre\"
)
endlocal
FOR 在后台启动另一个带有%ComSpec% /c 的命令进程,并将指定的命令行作为附加参数附加。因此,在后台将 Windows 安装到 C:\Windows 中执行:
C:\Windows\System32\cmd.exe /c dir "C:\Temp\*.jpg" /A-D /B /S 2>nul | %SystemRoot%\System32\findstr.exe /I /L /V /C:"\\pre\\" /C:"\\post\\"
DIR由后台命令进程执行搜索
- 在目录
C:\Temp 及其所有子目录中,因为选项/S
- 仅用于文件,因为选项
/A-D(属性不是目录)
- 匹配通配符模式
*.jpg
- 并由于选项
/B而以裸格式输出
- 由于选项
/S,仅包含具有完整路径的文件名。
这个文件名列表从后台命令进程的STDOUT(标准输出)重定向操作符|到的STDIN(标准输入) FINDSTR 搜索的内容
- 由于选项
/I而包含不区分大小写的行
- 文字字符串
\pre\ 或文字字符串\post\
- 并由于选项
/V 输出反转结果,即不行包含\pre\ 或\post\。
所以 FINDSTR 在这里用作过滤器,以从 DIR 输出的 *.jpg 文件名列表中获取完整路径,只是那些没有@的文件名987654340@ 或 \post\ 在其路径中排除已位于名称为 pre 或 post 的两个子目录之一中的 JPEG 文件。
2>nul 在命令 DIR 的参数之后,如果在 C:\Temp 及其子目录中找不到任何 *.jpg 文件名,则会抑制 DIR 输出的错误消息通过将写入STDERR(标准错误)的错误消息重定向到设备NUL。
阅读有关Using command redirection operators 的Microsoft 文章,了解2>nul 的解释。重定向运算符 > 和 | 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令 之前处理此命令行时被解释为文字字符FOR 在后台启动的单独命令进程中使用findstr 执行嵌入的dir 命令行。
FOR 与选项 /F 捕获所有写入以处理由 FINDSTR 启动的命令进程的 STDOUT 并在之后逐行处理此输出开始cmd.exe 自行终止。在这里处理捕获的文件名列表非常重要,并且不要在文件系统返回的另一个文件名之后迭代一个文件名,因为通配符模式匹配的文件 *.jpg 在目录结构中的每次循环迭代期间都会移动.因此,与 *.jpg 匹配的目录条目在每次循环迭代时都会发生变化,因此需要在移动文件之前将文件名列表加载到内存中。
FOR 带有选项 /F 会忽略此处没有出现的空行。
FOR 带有选项/F 将使用普通空格和水平制表符作为字符串分隔符将每一行拆分为子字符串,并将仅将第一个空格/制表符分隔的字符串分配给指定的循环变量I if不以默认行尾字符 ; 开头,在这种情况下,该行将像空行一样被完全忽略。
具有完整路径的文件名不能以; 开头。所以这里不能修改默认的eol=;。但是行拆分行为会适得其反,因为完整的限定文件名可以包含一个或多个空格。出于这个原因,选项delims= 用于定义字符串分隔符的空列表,它完全禁用行拆分行为。
因此,DIR 输出的每个完整文件名在由 FINDSTR 过滤掉的路径中不包含 \pre\ 或 \post\ 被分配给循环变量 I 一个一个接一个。
接下来检查当前 JPEG 文件是否存在子文件夹 pre,如果不存在则创建此文件夹。然后将当前 JPEG 文件移动到子目录 pre 中,并以完全相同的文件名覆盖 pre 中的文件。
所以这个批处理文件可以在C:\Temp 上执行多次,因为它会忽略所有子目录pre 和post 中的所有*.jpg 文件
要了解所使用的命令及其工作原理,请打开command prompt 窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
dir /?
echo /?
endlocal /?
findstr /?
for /?
if /?
md /?
move /?
setlocal /?