【问题标题】:CMD to delete a specific folder with files from multiple folder pathsCMD 删除包含来自多个文件夹路径的文件的特定文件夹
【发布时间】:2018-12-19 04:30:33
【问题描述】:

我需要一个 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 的日志文件

【问题讨论】:

  • 您是否尝试过使用父目录中的RD 命令,可能使用/S 选项? 在命令提示符处输入 RD /? 以获取命令使用信息。

标签: batch-file cmd command-line-interface batch-processing command-prompt


【解决方案1】:

首先,正如 Microsoft 文档 Naming Files, Paths, and Namespaces 所解释的,Windows 上的目录分隔符是 \,而不是 Linux/Mac 上的 // 在 Windows 上用于选项,您可以在代码中看到,例如 /Q。所以将来在文件/文件夹路径中使用\。访问内核函数的 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 带有选项/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 的标准输出使用 | 重定向,以处理运行的 FINDSTRSTDIN

  • 因为选项 /I 不区分大小写
  • 使用选项/R 明确请求正则表达式查找
  • 对于字符串\log \log-archive(空格被解释为OR)
  • 由于选项/E,必须在行尾找到。

所有符合这些搜索条件的行都由FINDSTR输出,以处理后台命令进程的STDOUT。使用 FINDSTR 过滤 DIR 的输出是必要的,以避免删除名为例如 LogToKeep 的目录,该目录也由 DIR 找到并输出强>。

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

带有选项/F

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

FOR 对每个目录输出执行 DIR 传递带有完整路径的 FINDSTR 过滤器命令 RD 删除由于选项 /Q 和所有文件和子目录由于 /S 而安静地目录。

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

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

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

@ 留给命令 FOR 和命令 RD 只是在 Windows 命令处理器 cmd.exe 执行之前抑制这些命令的输出。如果在包含@echo off 之前的批处理文件中使用此单个命令行,则不需要两个@

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

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

【讨论】:

  • 既然涉及到这么深,我认为很重要的一点是,%%I 指的是将在 for 循环中迭代的结果。 “对于结果集中的%%I,对每个%%I 执行操作。” I 可以是参数/变量的任何所需名称。
【解决方案2】:

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

这将删除“C:\Program Files\product\plugins”的任何子文件夹中的 log 和 log-archive 目录下的所有文件。文件夹必须准确命名为 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\*"

【讨论】:

  • 没有。 log 和 log-archive 是目录。考虑这个 C:\Program Files\product\plugins\plugin_Path\pluginOne\audit\log\*。提前谢谢你
  • 是的,中间子目录——存在于 'plugins' 和 'log'/'logarchive' 之间——forfiles 返回 ERROR: Files of type "log" not found
猜你喜欢
  • 2020-04-02
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 2020-05-03
  • 1970-01-01
相关资源
最近更新 更多