【问题标题】:Batch script that should only delete 0 byte files is deleting non 0 byte files and also in subfolders even without /s应该只删除 0 字节文件的批处理脚本正在删除非 0 字节文件以及子文件夹中,即使没有 /s
【发布时间】:2020-11-18 00:28:49
【问题描述】:

我有一个非常简单的 .bat 脚本来清理文件夹中的 0 字节文件:

@echo off
FORFILES /P "E:\Path" /C "CMD /C IF @FSIZE==0 del @FILE /Q"

问题是,即使我没有使用 /S 开关,它也会删除非 0 字节的文件并删除子文件夹中的所有文件。

【问题讨论】:

  • 您没有使用/S 选项,因此您的代码无法删除子文件夹中的文件。
  • 另外,@FILE 变量不包括文件路径,因此它会尝试删除当前工作目录中的文件,而不一定是E:\Path 中的文件。所以需要使用@path变量来删除文件。
  • @Squashman 我不知道该告诉你什么,这绝对是删除子文件夹中的文件,即使我使用@PATH 而不是@FILE。我已经测试了好几次,包括刚才,只是为了验证。

标签: batch-file del forfiles


【解决方案1】:

您可以使用for

@echo off
for /r %%A in (*.*) do if %%~zA==0 del "%%~fA" /q

这样,您将循环访问目录和子目录中的每个文件,并使用%%~zvar(在本例中为%%~zA)获取其大小。

然后,使用if 查看大小是否等于 0 字节。如果是,它将删除空文件。

【讨论】:

  • 不想删除子文件夹中的任何文件,只删除我指定的文件夹。
  • 去掉 /R 开关。
  • 好吧,至少它不会删除子文件夹中的东西。我仍然不知道为什么它不删除我的 0 字节文件。有趣的是,当我尝试在 CMD 中运行时收到以下消息:“此时是意外的。”
  • 感谢您的出色回答。这是一个比其他荒谬复杂的答案更好的答案。
  • 我认为这可能需要的唯一更改是引用第二个%%A,以便它处理包含一个或多个空格的路径名。你怎么看?
【解决方案2】:

这里有另一种 方法,它使用 来选择0 字节文件作为In 命令。我发现选择该块中的所有文件而不是在Do 部分中逐一过滤所有文件更有效。

如果您只删除*目录本身中的内容:

@For /F Tokens^=1* %%G In ('^""%__AppDir__%Robocopy.exe" "E:\Path" NULL /L /NC /NDL /NJH /NJS^|"%__AppDir__%findstr.exe" /RC:"^[\   \ ]*0[\ ]"^"')Do @Del /A/F "%%H"

或者,如果您想删除子目录中的那些,只需在您的Robocopy.exe 命令中添加/S 选项:

@For /F Tokens^=1* %%G In ('^""%__AppDir__%Robocopy.exe" "E:\Path" NULL /L /NC /NDL /NJH /NJS /S^|"%__AppDir__%findstr.exe" /RC:"^[\    \ ]*0[\ ]"^"')Do @Del /A/F "%%H"

为了确保电路板格式不会破坏上述示例, 匹配应该是:
^[\ TAB\空格]*0 kbd>[\TAB]

【讨论】:

  • 这不起作用。除了目标路径我还有什么需要改变的吗?
  • 我贴的是一个完整的批处理文件。为了测试我的代码@OatMaGoat,您必须创建一个新的批处理文件,其中只包含我发布的内容,除了E:\Path 之外没有其他任何添加、删除或修改(双引号之后仍应将其括起来! )。而且我知道代码有效,我使用它的时间比我愿意承认的要长......
  • 这正是我所做的;我创建了一个扩展名为 .bat 的新文件,使用 NPP 对其进行了编辑,并更改了E:\Path 部分。一定有其他事情发生,因为我也无法让fordel 正常工作,尽管我实际上是复制和粘贴它,只更改路径,将其保存为 *.bat,然后运行它,什么都没有发生。感谢您的回复;我最终通过 PS1 脚本找到了我需要的东西。
  • 您是否专门检查了站点软件没有修改代码,并确保它与我在答案脚下提供的布局相匹配?此外,如果您将其更改为@(For /F Tokens^=1* %%G In ('^""%__AppDir__%Robocopy.exe" "E:\Path" NULL /L /NC /NDL /NJH /NJS^|"%__AppDir__%findstr.exe" /RC:"^[\ \ ]*0[\ ]"^"')Do @Echo [%%G] "%%H")&Pause,它应该会显示文件大小及其名称。例如[0] "filename.ext" 如果输出正确,可能你遇到了一个愚蠢的问题,比如一个名为Del 的可执行文件,它正在接管内部命令Del