CMD 从多个文件夹路径中删除包含文件的特定文件夹

CMD to delete a specific folder with files from multiple folder paths

我需要一个 CMD 批处理文件来删除所有日志文件。 我公司为他们的产品制作插件,路径如下:

C:/Program Files/product/../plugins/../plugin_Path/pluginOne/audit/log
C:/Program Files/product/../plugins/../plugin_Path/pluginOne/audit/log-archive
C:/Program Files/product/../Root/plugins/../plugin_Path/pluginTwo/audit/log
C:/Program Files/product/../Root/plugins/../plugin_Path/pluginTwo/audit/log-archive

现在我需要删除所有日志和日志存档文件夹及其包含的内容。

目前我写了一个像这样的小程序:

@echo off
color 02
for %%A in (
    "C:/Program Files/product/plugins/plugin_Path/pluginOne/audit/log"
    "C:/Program Files/product/plugins/plugin_Path/pluginOne/audit/log-archive"
    "C:/Program Files/product/plugins/plugin_Path/pluginTwo/audit/log"
    "C:/Program Files/product/plugins/plugin_Path/pluginTwo/audit/log-archive"
    ) do (
    del /Q %%A
    echo Deleted %%A
)

echo All files deleted
pause
echo Program ended

但这里我需要手动插入所有日志路径。 我正在寻找一种解决方案,我可以在其中指向父文件夹(比如 Program Files/Company),它可以遍历其中的所有文件,并将删除所有日志和日志归档文件夹及其包含的文件夹。 我是一名 QA 人员,具有良好的 QA 经验,但没有批处理编程经验,而且我没有太多时间,支持团队也不在场。 [需要帮助]。存在 超过 1K 的日志文件

首先,如 Microsoft 文档 Naming Files, Paths, and Namespaces 所述,Windows 上的目录分隔符是 \ 而不是 Linux/Mac 上的 // 在 Windows 上用于选项,如您在代码中看到的那样,例如 /Q。因此,将来在 file/folder 路径中使用 \。 Windows 访问内核函数的文件系统会在访问文件系统之前自动将所有正斜杠替换为反斜杠,但是编写依赖于自动纠错的代码从来都不是一个好主意。

删除指定文件夹中名称为 loglog-archive 的所有文件夹及其所有子文件夹的任务可以使用单个命令行完成。

@for /F "delims=" %%I in ('dir "%ProgramFiles%\product\plugins\plugin_Path\log*" /AD /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /R "\log \log-archive"') do @rd /Q /S "%%I" 2>nul

FOR with option /F 在命令的后台以 cmd.exe /C(更精确的是 %ComSpec% /C)开始的单独命令进程中运行' 中的行... ' 在这里:

dir "C:\Program Files\product\plugins\plugin_Path\log*" /AD /B /S 2>nul | C:\Windows\System32\findstr.exe /E /I /R "\log \log-archive"

命令DIR输出处理STDOUT

  • 由于选项 /B
  • 为裸格式
  • 因为选项 /AD 只是目录(属性目录)
  • 与通配符模式匹配的目录名称log*
  • 在指定目录下C:\Program Files\product\plugins\plugin_Path
  • 及其所有子目录,因为选项 /S
  • 完整路径也是因为选项 /S

可能是 DIR 找不到符合这些条件的任何文件系统条目。在这种情况下,DIR 会输出一条错误消息来处理 STDERR。此错误输出使用 2>nul 重定向到设备 NUL 以抑制它。

DIR 的标准输出被 | 重定向到处理 STDINFINDSTR 运行

  • 因为选项 /I 不区分大小写
  • 使用选项 /R
  • 明确请求的正则表达式查找
  • for string \log or \log-archive (space 解释为 OR)
  • 由于选项 /E,必须在行尾找到它。

所有匹配这些搜索条件的行都由FINDSTR输出以处理后台命令进程的STDOUT。使用 FINDSTR 过滤 DIR 的输出是必要的,以避免删除名为 LogToKeep 的目录DIR.

输出

阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解 2>nul| 的解释。重定向运算符 >| 必须在 FOR 命令行上使用脱字符 ^ 进行转义,以便在 [=200= 时将其解释为文字字符] 命令解释器在执行命令 FOR 之前处理此命令行,该命令在后台启动的单独命令进程中执行嵌入式命令行。

FOR with option /F 捕获输出以处理启动命令进程的 STDOUT 并在之后逐行处理此输出开始 cmd.exe 自行终止。空行总是被 FOR 忽略,这里不会出现。以分号开头的行在默认情况下也会被忽略,因为 eol=; 是行尾选项的默认定义。但是完全限定的文件夹路径不能在开头包含分号,因为文件夹路径以驱动器号开头,或者在 UNC 路径的情况下以反斜杠开头。所以在这种情况下可以保留默认的行尾选项。 FOR 默认情况下会将每一行拆分为子字符串,使用普通 space 和水平制表符作为字符串分隔符,并且只会将第一个 space/tab 分隔的字符串分配给指定的循环变量.此处不需要此行拆分行为,因为文件夹路径肯定包含 space 字符,并且需要整个文件夹路径,而不仅仅是第一个 space 之前的字符串。出于这个原因,delims= 用于指定一个空的分隔符列表,它会禁用行拆分行为。

FORDIR 通过 FINDSTR 过滤器输出的每个目录执行完整路径命令 RD 由于选项 /Q 和所有文件和子目录,因为 /S.

悄悄删除目录

由于缺少 NTFS 权限,删除目录可能会失败,或者要删除的目录或其子目录之一是 运行 进程的当前目录,或者要删除的目录中的文件当前是由 运行 进程以拒绝在打开时删除文件的方式打开,或者要删除的目录不再存在,因为它已经在 FOR 循环中删除.命令 RD 处理 STDERR 的错误消息在这种情况下被重定向到设备 NUL 以抑制它。

请注意,命令 RD 会删除所有 loglog-archives 目录,而不仅仅是这些目录中的文件和子目录。从你的问题中不清楚批处理文件究竟应该删除什么。

当然也可以将rd /Q /S "%%I"替换为del /A /F /Q "%%I\*"以仅删除所有文件,包括隐藏文件和只读文件,这些文件在分配有循环变量完整路径的目录中安静地删除I.

@ 留给命令 FOR 和命令 RD 只是在 [=200 执行之前抑制这些命令的输出=] 命令处理器 cmd.exe。如果在包含 @echo off.

之前的批处理文件中使用此单个命令行,则不需要两个 @

要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • del /?
  • dir /?
  • findstr /?
  • for /?
  • rd /?

如果您想删除日志和日志存档目录的内容。这意味着最简单的解决方案可能是 FORFILES.

这将删除在 "C:\Program Files\product\plugins" 的任何子文件夹中找到的日志和日志存档目录下的所有文件。文件夹必须准确命名为 loglog-archive。它不会删除目录。

 FORFILES /P "C:\Program Files\product\plugins" /M log /C "cmd /c if @isdir==TRUE DEL /s /q @path\*"
 FORFILES /P "C:\Program Files\product\plugins" /M log-archive /C "cmd /c if @isdir==TRUE DEL /s /q @path\*"

您还可以添加一个 /D 开关以仅删除超过特定天数的适用文件。这将删除 "C:\Program Files\product\plugins" 下超过 90 天的所有日志和日志存档文件:

 FORFILES /D -90 /P "C:\Program Files\product\plugins" /M log /C "cmd /c if @isdir==TRUE DEL /s /q @path\*"
 FORFILES /D -90 /P "C:\Program Files\product\plugins" /M log-archive /C "cmd /c if @isdir==TRUE DEL /s /q @path\*"