如果在子文件夹中多次找到文件 - 使用批处理脚本删除所有文件

If a file was found more than once in subfolders - delete all using batch script

我正在使用的系统如下所示:

D:\TargetFolder\Subfolder1 
D:\TargetFolder\Subfolder2\Subfolder3

这些文件夹中可能存在一个名为 "Settings.txt" 的文件。我想要的是以下内容:

最终脚本可能是这样的:

IF exist "D:\TargetFolder\*Settings.txt" (goto delete) else goto continue
:delete
del *Settings.txt /f /q
:continue
exit

希望我正确解释了我的问题。 提前致谢。

此批处理文件可用于任务:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SettingsFile="
for /F "delims=" %%I in ('dir "D:\TargetFolder\Settings.txt" /A-D-L /B /S 2^>nul') do if not defined SettingsFile (set "SettingsFile=1") else (del "D:\TargetFolder\Settings.txt" /A /F /Q /S >nul 2>nul & goto Continue)
:Continue
endlocal

上面的一个不太紧凑的变体:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SettingsFile="
for /F "delims=" %%I in ('dir "D:\TargetFolder\Settings.txt" /A-D-L /B /S 2^>nul') do (
    if not defined SettingsFile (
        set "SettingsFile=1"
    ) else (
        del "D:\TargetFolder\Settings.txt" /A /F /Q /S >nul 2>nul
        goto Continue
    )
)
:Continue
endlocal

首先,确保环境变量SettingsFile不是偶然定义的。

接下来,命令 DIR 由在后台启动的单独命令进程执行,以在 D:\TargetFolder 中搜索名称为 Settings.txt 的文件并将它们全部输出带完整路径。 DIR 的输出被 FOR 捕获,如果 DIR 找到文件 Settings.txt 完全没有。

环境变量 SettingsFile 是用一个字符串值定义的,它在第一个文件 Settings.txt 上并不重要。如果没有更多的文件 Settings.txt.

FOR 循环结束而没有做任何其他事情

但是在第二个文件 Settings.txt 上执行命令 DEL 以删除指定文件夹及其所有子文件夹中的文件 Settings.txt。循环被命令 GOTO 激发,继续在标签 Continue 下面的行上处理批处理文件,因为 Settings.txt 的其他出现不再重要,当然可以删除所有 Settings.txt 成功后不再存在。

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

  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

阅读有关 Using command redirection operators 的 Microsoft 文档,了解 >nul2>nul 的解释。重定向运算符 > 必须在 上用脱字符 ^ 进行转义,以便在 Windows 命令解释器处理此命令时将其解释为文字字符 命令行执行命令 FOR 之前的行,该命令在后台启动的单独命令进程中执行嵌入式 dir 命令行 cmd.exe /c' 中的命令行作为附加参数附加。

有关运算符 & 的解释,另请参阅 single line with multiple commands using Windows batch file

如果您可以使用 Windows 系统上已有的 PowerShell,这并不困难。如果找到的文件数大于零,则删除每个文件。否则,什么也不会发生。当您确信正确的文件将被删除时,从 Remove-Item 命令中删除 -WhatIf

@powershell.exe -NoLogo -NoProfile -Command ^
    "$Files = Get-ChildItem -Recurse -File -Path 'C:\TargetFolder' -Filter 'Settings.txt';" ^
    "if ($Files.Count -gt 1) {" ^
        "foreach ($File in $Files) { Remove-Item $File.FullName -Whatif }" ^
    "}"

如果可以 运行 作为 PowerShell .ps1 脚本文件,可以消除一些噪音。

$Files = Get-ChildItem -Recurse -File -Path 'C:\TargetFolder' -Filter 'Settings.txt'
if ($Files.Count -gt 1) {
    foreach ($File in $Files) { Remove-Item $File.FullName -Whatif }
}
@echo off

for /F "skip=1" %%a in ('dir /B /S D:\TargetFolder\Settings.txt 2^>NUL') do (
   del /Q /S D:\TargetFolder\Settings.txt >NUL
   goto break
)
:break

for /F循环处理来自dir /S命令的文件名,但是第一个被跳过(因为"skip=1"切换),也就是说,如果有多个文件,执行下一条指令

for 中的第一个命令删除名称为“Settings.txt”的所有文件并且 for 被中断,因为 goto 命令。