FORFILES:仅当 RELPATH 包含子字符串时才删除文件

FORFILES: Only delete file if RELPATH contains substring

在另一个 topic 中,我找到了以下代码片段来检查字符串是否包含子字符串。

if not x%str1:bcd=%==x%str1% echo It contains bcd

现在我正尝试在我的 FORFILES 方法中实现它。 FORFILES 应删除包含子字符串 'IMG' 的子文件夹中的 XML 个文件。我修改了代码如下:

set loglocation=C:\Tools\PurgeOldFiles\log\DELETEOLD_XML_IMG.txt
set olderthan=30
set source=X:\Test
set extension=XML

FORFILES -p%source% -s -m*.%extension% -d-%olderthan% -c"CMD /C if not x@RELPATH:img=%==x@RELPATH DEL @PATH\@FILE /q & echo @PATH\@FILE deleted." >> %loglocation%

它不会删除 IMG 子文件夹中的旧文件(超过 30 天)XML。

我想我在 "x@RELPATH:img=%==x@RELPATH" 中有某种(语法)错误。

您将需要一个临时环境变量,比如 VAR,并需要延迟扩展来实现它。


首先让我们构建需要在forfiles循环中执行的代码:

if @isdir==FALSE (
    set VAR=@relpath
    if not #!VAR:%search%=!==#!VAR! (
        del /Q @path
        echo @path deleted.
    )
)

这会执行以下步骤:

  • 判断匹配项是否为文件,否则跳过;
  • @relpath的值赋给变量VAR;请注意 @relpath 已扩展为包含在 "";
  • 中的相对路径
  • 检查扩展的相对路径是否包含至少一个搜索字符串实例,如果没有则跳过其余部分;请注意,搜索是以不区分大小写的方式进行的;
  • 删除匹配路径,return相关日志信息; @path 已经包含文件名加上扩展名,所以你不需要 @file;

现在让我们把上面的代码写成一行,和forfiles:

放在一起
set "loglocation=C:\Tools\PurgeOldFiles\log\DELETEOLD_XML_IMG.txt"
set "olderthan=30"
set "source=X:\Test"
set "extension=XML"
set "search=img"

forfiles /S /P "%source%" /M "*.%extension%" /D -%olderthan% /C "cmd /V:ON /C 0x22if @isdir==FALSE ((set VAR=@relpath) & if not #!VAR:%search%=!==#!VAR! (del /Q @path & echo @path deleted.))0x22" >> "%loglocation%"

cmd/V开关开启延迟扩展; !VAR! 语法使用了它(与 %VAR% 相对)。输入 cmd /? 以获得更多信息。


备注:

img 子字符串的搜索不关心在何处(在路径中的哪个级别)找到匹配项,也不检测出现了多少匹配项。

请注意 forfiles 的开关 /S 使其递归枚举给定目录。

您不能直接对 FORFILES 变量执行 find/replace。我会使用带有正则表达式的 FINDSTR 来确定文件夹路径是否包含 IMG。您可以将输出重定向到 NUL 并仅在使用 &&.

找到时有条件地执行命令

其他问题:

  • 您只需要在 DEL 和日志语句中使用 @PATH - 它包含完整路径,包括文件名。
  • 不需要 DEL /Q 选项,因为没有通配符。
  • 如果 DEL 成功,您应该只回显删除消息。但是 DEL 不会设置错误级别或在失败时激活 ||,即使它会向 stderr 打印一条错误消息。您可以将 DEL stderr 重定向到 stdout 并通过管道传输到 FINDSTR 以确定是否有错误消息,并使用 ||&& 采取适当的措施。

如果 IMG 在路径中的任何位置,或者仅当它在父文件夹中,您不清楚是否要删除文件。

如果 IMG 出现在文件夹路径中的任何位置,以下内容将删除文件:

set loglocation=C:\Tools\PurgeOldFiles\log\DELETEOLD_XML_IMG.txt
set olderthan=30
set source=X:\Test
set extension=XML

forfiles /p "%source%" /s /m "*.%extension%" /d -%olderthan% /c "cmd /c echo @RELPATH|findstr /i IMG.*[\] >nul &&(del @PATH 2>&1|findstr 0x22^0x22>nul&&echo unable to delete @PATH||echo deleted @PATH)"  >>"%loglocation%"

稍微复杂一点的正则表达式将删除限制为仅当 IMG 出现在父文件夹中时

set loglocation=C:\Tools\PurgeOldFiles\log\DELETEOLD_XML_IMG.txt
set olderthan=30
set source=X:\Test
set extension=XML

forfiles /p "%source%" /s /m "*.%extension%" /d -%olderthan% /c "cmd /c echo @RELPATH|findstr /i 0x22IMG[^\]*[\][^\]*[=11=]x22 >nul &&(del @PATH 2>&1|findstr 0x22^0x22>nul&&echo unable to delete @PATH||echo deleted @PATH)"  >>"%loglocation%"