批处理命令以删除所有指定名称的子文件夹

60

我有一个这样的目录:

D:\Movies
D:\Movies\MovieTitle1\backdrops\
D:\Movies\MovieTitle2\backdrops\
D:\Movies\MovieTitle3\backdrops\
D:\Movies\MovieTitle4\backdrops\

如何编写批处理文件以删除所有名为“Backdrops”的文件夹?如果可能的话,我希望它可以从D:\驱动器开始递归运行。

4个回答

102

简短回答:

FOR /d /r . %%d IN (backdrops) DO @IF EXIST "%%d" rd /s /q "%%d"

我从Stack Overflow的无数相同问题的答案中得到了我的答案:

命令行工具在Windows中递归删除指定名称的文件夹?

这个命令没有经过测试,但我相信这个网站足够可靠,所以发布这个答案。

Alex在评论中建议的,这个批处理脚本应该是万无一失的:

D:
FOR /d /r . %%d IN (backdrops) DO @IF EXIST "%%d" rd /s /q "%%d"

3
如果您想在 D:\ 上运行此文件,您需要将其放入 D:\ 中,或者在 for /d /r 循环之前添加 cd /d D:\ - Alex
18
要将此内容用于批处理文件中,您需要转义“%”字符,即将每个“%d”替换为“%%d”。 - vgru
对我没用,尝试使用(node_modules),但不起作用-从浏览器搜索显示数百个“node_modules”文件夹。 - dermoritz
2
在Windows 7上,我不得不更改命令的一部分为"%d" rd /S /Q "%d"(大写的/s和/q)。否则,将被拒绝访问非空目录。 - Łukasz Rząsa
5
要在CMD提示符中直接运行此命令,请将“%%d”替换为“%d”。 - Satadru Biswas
显示剩余2条评论

22
上面的答案对我没用。我必须使用 @itd 的解决方案和 @Groo 的评论组合起来。向他们致敬。
对我来说最终的解决方案是(使用背景文件夹示例):
FOR /d /r . %%d IN ("backdrops") DO @IF EXIST "%%d" rd /s /q "%%d"

3
以上内容适用于批处理文件中的命令。如果您想在命令行中键入此命令,则需要执行 FOR /d /r . %d IN ("__pycache__") DO @IF EXIST "%d" rd /s /q "%d" - Shital Shah
我得到了 zsh: unknown file attribute: _ - Tjorriemorrie
@Tjorriemorrie 这段代码是为“Windows DOS”命令行(也称为cmd)编写的,我认为您正在使用Z shell(zsh)。 - JDC
2
好的,这对我也有效。我有很多来自2/3个驱动器的3k+ node_modules目录。因此,为了删除它们所有,我创建了cmd.bat文件并添加了以下代码:FOR /d /r . %%d IN ("node_modules") DO @IF EXIST "%%d" rd /s /q "%%d",它起作用了。 - maheshwaghmare
你能否指定完整路径(“C:\ Test \ xxx \ yyy”)而不仅仅是“backdrops”文件夹名称? - luisdev

17
我会提供一个不同的答案,因为在评论中会太拥挤了。有人问如果想要从/到不同文件夹执行该怎么办,并且我想给出非递归删除的示例。
首先,在cmd中使用该命令时,您必须使用“%d”,但是在.bat文件中使用时,您必须使用“%%d”。
您可以使用通配符来处理以"backdrops"开头的文件夹,例如:"backdrops*"。
递归删除以.bat文件所在文件夹开始的文件夹:
FOR /d /r . %d IN ("backdrops") DO @IF EXIST "%d" rd /s /q "%d"
在.bat文件所在文件夹中进行非递归删除(与通配符一起使用,因为无论如何您都不能有多个具有相同名称的文件夹):
FOR /d %d IN ("backdrops*") DO @IF EXIST "%d" rd /s /q "%d"
递归删除从您选择的文件夹开始的文件夹:
FOR /d /r "PATH_TO_FOLDER" %d IN ("backdrops") DO @IF EXIST "%d" rd /s /q "%d"
在您选择的文件夹中进行非递归删除(与通配符一起使用,因为无论如何您都不能有多个具有相同名称的文件夹):
FOR /d %d IN ("PATH_TO_FOLDER/backdrops*") DO @IF EXIST "%d" rd /s /q "%d"

6
我从 .Net 开发者的角度看待这个问题。有时需要递归地从批处理脚本所在的目录开始,清除所有 */bin/ 和 */obj/ 子文件夹。
我尝试了上述解决方案并注意到一个关键点:
与FOR命令的其他变体不同,在 'folder_set' 中必须包含通配符 ( * 或 ? ) 才能返回一致的结果。
来源: https://ss64.com/nt/for_d.html 在删除每个找到的结果之前添加echo,可以确保没有误报匹配。当我这样做时,我发现使用(obj)folder_set而没有通配符会触发DO表达式每个子文件夹的操作,即使它不匹配掩码。例如删除 "/.git/objects/" 目录是不好的。在掩码末尾添加一个问号(0或1个除点外的任何符号)可以解决此问题:
@echo off

FOR /d /r %%F IN (obj?) DO (
    echo deleting folder: %%F
    @IF EXIST %%F RMDIR /S /Q "%%F"
)

FOR /d /r %%F IN (bin?) DO (
    echo deleting folder: %%F
    @IF EXIST %%F RMDIR /S /Q "%%F"
)

同样适用于其他任何掩码。例如,清除缓存的库以使备份归档更轻巧(如“packages”和“node_modules”)。

2
这个很好用,但你需要在RMDIR行中的%%F变量周围加上双引号,以便长路径不会被跳过。@IF EXIST %%F RMDIR /S /Q "%%F"而非常长的路径可能仍然会产生错误。 - Michael Argentini
1
你也可以在批处理文件的顶部创建一个空目录:mkdir \empty,然后在每个RMDIR行的上面插入此行以在删除之前清除内容。这将处理无法通过RMDIR删除的长路径项:@IF EXIST %%F robocopy "\empty" "%%F" /MIR。最后通过删除空目录来完成批处理文件:rmdir /empty - Michael Argentini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接