如何在Windows命令提示符中删除特定目录下的文件/子文件夹

397

假设有一个变量叫做 %pathtofolder%,它清楚地说明了这是一个文件夹的完整路径。

我想要删除该目录中的每个文件和子文件夹,但不包括该目录本身。

但是,在执行删除操作时可能会出现“此文件/文件夹已在使用中”的错误...当出现这种情况时,应该继续执行并跳过该文件/文件夹。

是否有相应的命令可供使用?


可能是What ever happened to deltree, and what's its replacement?的重复问题。 - Rosberg Linhares
1
Windows 删除文件夹或者以点开头的文件夹真是太难了,简直让人发疯。不过幸好 Windows 有 Bash 集成!在 Windows 10 中可以使用 rm -rf path\to\folder 命令删除文件夹(或者也可以从 Git Bash 中执行该命令)。总之,如果你遇到这种问题,不妨试试这个方法! - Stijn de Witt
16个回答

433

rmdir 是我最喜欢的用于删除文件和带有子文件夹的大型文件夹的命令。使用此命令时不会创建备份,因此在运行此命令之前,请确保已安全地复制了您的文件。

RMDIR "FOLDERNAME" /S /Q

这会静默删除文件夹及其所有文件和子文件夹。


87
这似乎删除了原帖作者想保留的文件夹路径。 - Fuzz Evans
5
这将会删除文件夹本身,因此您需要添加另一个命令:md 文件夹名称(参见下面 @rakoczyn的答案)。 - thdoan
4
在这里,“backup is created” 意思是“备份已创建”,但您无法看到任何会创建任何类型备份的内容。 - Paul Groke
2
目录不为空,消息作为响应返回! - Jamshaid K.
18
为了不删除该文件夹本身,在操作之前将其设置为当前目录,然后使用“.”作为FOLDERNAME。重新创建它并不一定相同,因为ACLs可能会丢失。cd "FOLDERNAME" RD . /S /Q - Moritz Both
显示剩余6条评论

303

您可以使用此Shell脚本清理C:\Temp文件夹中的文件。 来源:

del /q "C:\Temp\*"
FOR /D %%p IN ("C:\Temp\*.*") DO rmdir "%%p" /s /q

创建一个批处理文件(比如delete.bat),将上述命令写入其中。进入delete.bat所在的位置,然后运行命令:delete.bat。


21
我尝试了一下,但不幸的是文件没有被删除,只有子文件夹被删除了。例如,我有一个名为“测试”的文件夹,它包含两个名为“Ripon”和“Wasim”的文件夹,并且包含一个名为“riponalwasim.txt”的文件。子文件夹Ripon和Wasim已被删除,但riponalwasim.txt未被删除。 - Ripon Al Wasim
19
如果您希望直接从命令行运行,请使用单个百分号,例如 %p - Alex
2
很遗憾这需要两行,但至少它能工作!我已经厌倦了寻找可用的“一行代码”,所以我会采用这个,谢谢! - nightcoder
3
你可以使用 '&&' 操作符在一行中执行两个命令而不需要一个批处理文件(注意单个 '%' 而不是 '%%')。 del /s /q "myfolder*" && FOR /D %p IN ("myfolder*") DO rmdir "%p" /s /q - ravinsp
1
命令行中的__DEL__命令缺少选项/A,以便删除设置了隐藏属性的文件,并且缺少选项/F,以便删除设置了只读属性的文件。因此,最好使用del /A /F /Q "C:\Temp\*"。而__FOR__命令行应修改为for /F "eol=| delims=" %%I in ('dir "C:\Temp\*" /AD /B 2^>nul') do rd /Q /S "C:\Temp\%%I",因为__FOR__会忽略设置了隐藏属性的目录。带有选项/AD /B的__DIR__输出C:\Temp中所有目录及其名称。 - Mofi
显示剩余6条评论

95

我能想到的最简单的解决方法是删除整个目录,具体操作如下:

RD /S /Q folderPath

然后再创建这个目录:

MD folderPath

6
如果您有删除文件夹的权限,但没有创建新文件夹的权限会怎样?我希望这是可能的 :) - Sandy
14
这是一个糟糕的解决方案,因为它在文件系统上引入了一个竞态条件,也就是说,如果第二个命令紧接着被执行,它可能会失败。 - Rok Strniša
27
如果目录有特殊权限,你刚刚搞砸了 (哎呀) ,这是个不好的解决方法。 - Immortal Blue
不要被“目录不为空”的响应吓到,只需执行两次命令即可 :-) - Kieran Ryan
2
RD和RMDIR是相同的命令,而且你在别人已经给出相同答案9个月后才回答,为什么人们还要给你积分呢? - user1853517
这个回答是否满足需求:“当出现类似于'此文件/文件夹已在使用中'的错误时,应该继续并跳过该文件/文件夹。”? - Peter Mortensen

62

这将删除文件夹和文件,并保留文件夹。

pushd "%pathtofolder%" && (rd /s /q "%pathtofolder%" 2>nul & popd)

5
对于那些不确定此方法的人:它绝对不会重新创建目录。如果没有2>nul,它会输出“由于正在被另一个进程使用,无法访问该文件。” - Rok Strniša
9
我讨厌Windows不能删除被某些程序使用的文件和文件夹。我喜欢你在这个一行代码中充分利用了它。 - andref
2
这就是我们在Windows中清空文件夹的超级魔法吗?令人印象深刻 :) - mlvljr
3
只有在您想保留父文件夹时才需要这样做。"RD /?" 命令可以显示清空文件夹的简单方法。 - foxidrive
2
如果你需要回到起始位置,这很好用,否则只需使用 CD mypath && RD /S . 即可。但我不喜欢你必须重复输入路径两次,对于较长的路径来说,这会变得难以阅读。因此,我会在开头添加 set p="mypath" - Amit Naidu
显示剩余4条评论

45
@ECHO OFF

SET THEDIR=path-to-folder

Echo Deleting all files from %THEDIR%
DEL "%THEDIR%\*" /F /Q /A

Echo Deleting all folders from %THEDIR%
FOR /F "eol=| delims=" %%I in ('dir "%THEDIR%\*" /AD /B 2^>nul') do rd /Q /S "%THEDIR%\%%I"
@ECHO Folder deleted.

EXIT

...删除给定目录下面的所有文件和文件夹,但不包括该目录本身。


4
这应该是正确的答案。只需简单地删除“deletemyfoldercontents.bat”文件,然后输入您的路径,它就能像魔法一样运行。 - timbrown
3
__DEL__命令行缺少选项/A,无法删除带有隐藏属性设置的文件,而且%dir%\*应该用双引号括起来,如"%dir%\*",以便于处理包含空格或以下这些字符之一的目录&()[]{}^=;!'+,`~。而且,因为__FOR__忽略具有隐藏属性设置的目录,所以__FOR__命令行应该修改为 for /F "eol=| delims=" %%I in ('dir "%dir%\*" /AD /B 2^>nul') do rd /Q /S "%dir%\%%I"。__DIR__带有选项/AD /B可以输出所有目录并只显示它们的名称。顺便说一下:dir不是一个好的环境变量名称。 - Mofi
1
不删除子文件夹 - RASMiranda
1
@RMiranda,在我的测试中,它完全按照OP的要求执行。您有一个不删除子文件夹的情况吗? - thepip3r
这个回答是否满足“可能会出现'此文件/文件夹已在使用中'等错误...当发生这种情况时,它应该继续并跳过该文件/文件夹”的要求? - Peter Mortensen
@PeterMortensen 是的,看起来是这样。我在临时文件夹上使用它,该文件夹中的文件正在被其他服务使用,它会报错但会跳过并继续移动到下一个文件。 - ScottN

35
CD [Your_Folder]
RMDIR /S /Q .

当您使用RMDIR命令删除当前目录时,会收到一条错误消息,告诉您无法访问当前文件夹,因此无法删除它。

更新:

根据这个有用的评论(感谢Moritz Both),您可以在两个命令之间添加&&,以便RMDIR不会在CD命令失败时运行(例如,输入错误的目录名称):

CD [Your_Folder] && RMDIR /S /Q .

来源于Windows 命令行参考:

/S:删除目录树(指定目录及其所有子目录,包括所有文件)。

/Q:指定安静模式。删除目录树时不需要确认(注意,只有在指定了 /s 的情况下才适用 /q)。


1
这对于清空临时文件夹来说非常完美,但是cd [Your_Folder]非常关键-我必须记住这一点,以免删除目录本身... - sage
5
这是正确的解决方案。在命令之间添加 && 而不是换行符,这样就可以避免 CD 失败。 - Moritz Both
这是一个简单而正确的解决方案。甚至可以在Azure命令行中使用! - Philippe
相当糟糕的解决方案...例如,我需要这个命令行删除用于svn更新 - 我想在进行更新svn之前删除所有文件和文件夹,因为可能会有一些更改在我使用此机器上,但相关的只有已检入的项目。执行RMDIR /S /Q .也会删除SVN链接,因此使该文件夹不再是svn文件夹。 - Dominik Lemberger
这与前面的四个答案有何不同? - Peter Mortensen

15

我使用PowerShell

Remove-Item c:\scripts\* -recurse

它会删除文件夹中的内容,而不是文件夹本身。


rhellem 的回答是最近的,但它是唯一能为我做到这一点的答案。(Win 8.1,不是出于选择) - philologon
4
从批处理命令行中执行:powershell -Command "Remove-Item 'PathToMyDirectory\*' -Recurse -Force" - Rosberg Linhares
请注意,"*"符号是必需的,否则将会删除整个文件夹。 - mhenry1384

14

除了由foxidrive发布的单个命令行之外,所有发布于2018-06-01的答案都不能完全删除%PathToFolder%文件夹中的所有文件和所有文件夹/目录。这就是为什么要发布一个更简单的单行命令来删除文件夹中的所有文件和子文件夹,以及一个更复杂的批处理文件,解释了为什么所有其他使用DELFORRD的2018-06-01发布的答案都无法完全清理文件夹的原因。


可以在批处理文件中使用的简单单行命令解决方案:

pushd "%PathToFolder%" 2>nul && ( rd /Q /S "%PathToFolder%" 2>nul & popd )

这个命令行包含三个依次执行的命令。

第一个命令PUSHD将当前目录路径压入堆栈,然后将%PathToFolder%设为运行命令进程的当前目录。

默认情况下,即使是UNC路径,因为启用了命令扩展,所以这也适用于它。在这种情况下,PUSHD会创建临时驱动器字母,指向指定的网络资源,然后使用新定义的驱动器字母更改当前驱动器和目录。

如果指定的目录根本不存在,则PUSHD会输出以下错误消息以处理STDERR:

The system cannot find the path specified.

通过将2>nul重定向到设备NUL,可以抑制此错误消息。

只有在成功将当前命令进程的当前目录更改为指定目录时,即指定目录确实存在时,才会执行下一个命令RD

带选项/Q/S的命令RD安静地删除一个带有所有子目录的目录,即使该指定目录包含具有隐藏属性或设置为只读属性的文件或文件夹。系统属性永远不会防止文件或文件夹的删除。

未删除的项目:

  1. 任何正在运行的进程的当前目录所使用的文件夹。对于任何正在运行的进程使用的整个文件夹树都不能被删除。

  2. 由任何正在运行的进程打开的文件,其在文件打开时设置了文件访问权限以防止在运行应用程序/进程时删除文件。这样打开的文件也会防止删除到已打开文件的整个文件夹树。

  3. 当前用户没有删除文件/文件夹所需的(NTFS)权限的文件/文件夹。这也会阻止删除与此文件/文件夹相对应的文件夹树。

不删除文件夹的第一个原因是使用此命令行删除指定文件夹的所有文件和子文件夹,但不删除文件夹本身。该文件夹被暂时设置为运行命令进程的当前目录,从而阻止删除文件夹本身。当然,这导致了RD命令输出错误消息:

The process cannot access the file because it is being used by another process.

File这里用词不当,因为实际上是另一个进程,即执行RD命令的当前命令进程正在使用该文件夹。事实上,对于文件系统来说,文件夹是具有文件属性directory的特殊文件,这解释了此错误消息。但我不想深入研究文件系统管理。

像所有其他可能发生的错误消息一样,由于上述三个原因之一,此错误消息也通过将STDERR处理程序重定向到设备NUL2>nul进行抑制。

第三个命令POPD会独立于命令RD的退出值执行。POPD命令弹出由PUSHD推送到堆栈中的目录路径,并将运行命令进程的当前目录更改为该目录,即还原初始的当前目录。POPD删除%PathToFolder%为UNC文件夹路径的情况下PUSHD创建的临时驱动器号。

注意:在特定情况下,例如初始当前目录是要清理的目录的子目录,但该目录已不存在,POPD可能会在恢复初始当前目录时悄悄地失败。在这种特殊情况下,%PathToFolder%保留为当前目录。因此,建议不要从%PathToFolder%的子目录运行上述命令行。

另一个有趣的事实:我还使用UNC路径尝试过命令行,在Windows 7上共享本地目录C:\Temp并使用UNC路径\\%COMPUTERNAME%\Temp\CleanTest分配给环境变量PathToFolder。如果运行命令行的当前目录是使用UNC路径访问的共享本地文件夹的子目录,即C:\Temp\CleanTest\Subfolder1,则Subfolder1将被RD删除,接下来POPD在将C:\Temp\CleanTest\Subfolder1再次作为当前目录时会悄悄失败,导致Z:\CleanTest保持为运行命令进程的当前目录。因此,在这种非常特殊的情况下,临时驱动器号一直存在,直到将当前目录更改为实际存在的本地目录,例如cd /D %SystemRoot%。不幸的是,如果POPD无法恢复初始当前目录,则不会以大于0的值退出,从而无法仅通过POPD的退出代码检测此非常特殊的错误条件。不过,可以认为几乎没人会遇到这种非常特殊的错误情况,因为UNC路径通常不用于访问本地文件和文件夹。

为了更好地理解所使用的命令,请打开一个命令提示符窗口,在其中执行以下命令,并非常仔细地阅读显示的每个命令的帮助。

  • pushd /?
  • popd /?
  • rd /?

使用Windows批处理文件的单行多个命令解释了此处使用的&&&运算符。


接下来,让我们看一下使用DEL命令删除%PathToFolder%中的文件以及使用FORRD删除%PathToFolder%中子文件夹的批处理文件解决方案。

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Clean the folder for temporary files if environment variable
rem PathToFolder is not defined already outside this batch file.
if not defined PathToFolder set "PathToFolder=%TEMP%"

rem Remove all double quotes from folder path.
set "PathToFolder=%PathToFolder:"=%"

rem Did the folder path consist only of double quotes?
if not defined PathToFolder goto EndCleanFolder

rem Remove a backslash at end of folder path.
if "%PathToFolder:~-1%" == "\" set "PathToFolder=%PathToFolder:~0,-1%"

rem Did the folder path consist only of a backslash (with one or more double quotes)?
if not defined PathToFolder goto EndCleanFolder

rem Delete all files in specified folder including files with hidden
rem or read-only attribute set, except the files currently opened by
rem a running process which prevents deletion of the file while being
rem opened by the application, or on which the current user has not
rem the required permissions to delete the file.
del /A /F /Q "%PathToFolder%\*" >nul 2>nul

rem Delete all subfolders in specified folder including those with hidden
rem attribute set recursive with all files and subfolders, except folders
rem being the current directory of any running process which prevents the
rem deletion of the folder and all folders above, folders containing a file
rem opened by the application which prevents deletion of the file and the
rem entire folder structure to this file, or on which the current user has
rem not the required permissions to delete a folder or file in folder tree
rem to delete.
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul

:EndCleanFolder
endlocal

批处理文件首先确保环境变量PathToFolder被定义为一个没有双引号和末尾没有反斜杠的文件夹路径。末尾的反斜杠并不会产生问题,但是由于在批处理文件执行期间PathToFolder的值会与其他字符串拼接,因此文件夹路径中的双引号可能会导致问题。

重要的是这两行代码:

del /A /F /Q "%PathToFolder%\*" >nul 2>nul
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul

DEL命令用于删除指定目录中的所有文件。

  • 选项/A是必需的,以便处理所有文件,包括带有隐藏属性的文件,否则DEL将忽略这些文件而不使用选项/A
  • 选项/F是必需的,以便强制删除设置了只读属性的文件。
  • 选项/Q是必需的,以便在删除多个文件时运行静默删除,而无需提示用户是否确实要删除多个文件。
  • >nul是必需的,以便将写入到STDOUT句柄的文件名输出重定向到设备NUL,因为该文件当前已打开或用户没有删除该文件的权限。
  • 2>nul是必需的,以便将无法删除的每个文件的错误消息输出从STDERR句柄重定向到设备NUL

命令FORRD用于删除指定目录中的所有子目录。但由于FOR在这种情况下会忽略设置了隐藏属性的子目录,因此不使用for /D。出于这个原因,使用for /F在后台启动一个单独的命令进程,以%ComSpec% /c运行以下命令行:

dir "%PathToFolder%\*" /AD /B 2>nul

DIR 带有 /B 参数时以裸格式输出目录项,即在指定目录中独立于其他属性(如隐藏属性)列出所有子目录的名称,但不包括路径。2>nul 用于将DIR在未找到目录时生成的错误消息从处理程序 STDERR 重定向到设备 NUL

为了让FOR命令行被解释为字面字符,在Windows命令解释器执行此命令前必须使用控制字符^转义重定向运算符>。该FOR命令会启动一个后台进程,执行嵌入的dir命令行,并处理启动命令进程的句柄STDOUT捕获的输出内容,即子目录的名称,这些名称没有路径,也不用双引号括起来。

因为/B选项不会输出空行,所以FOR命令忽略不含内容的行;并且默认情况下,FOR命令会忽略以分号开头的行,而目录名可以以分号开头。因此,需要使用eol=|定义竖线字符为行尾字符,因为不能有目录或文件名包含它。

FOR命令会使用空格和水平制表符作为分隔符拆分行,并将仅第一个空格/制表符分隔的字符串分配给指定的循环变量I。由于目录名可能包含一个或多个空格,因此这种拆分行为在此处不需要。因此,使用delims=定义分隔符为空列表,以禁用行拆分行为,并始终将整个目录名分配给循环变量I

FOR将针对每个没有路径的子目录名称运行RD命令,这就是为什么在RD命令行上必须再次指定文件夹路径的原因,该路径与子文件夹名称进行连接。

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

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

13

RD是REMOVE Directory的缩写。

/S:删除该文件夹本身以及所有子文件夹和文件。使用此选项可删除整个文件夹树。

/Q:安静模式 - 不显示是否确认。

示例:

RD /S /Q C:/folder_path/here

2
因为你是唯一一个解释 /S/Q 的人,所以我点了赞。 - SourceVisor
3
rd个命令与rmdir相同,它将删除目录本身,这不是OP想要的。 - WesternGun
这个答案是否满足以下的需求:“可能会出现'此文件/文件夹已在使用中'之类的错误...当发生这种情况时,它应该继续并跳过该文件/文件夹。”?例如,它是否完全中止而不是继续执行? - Peter Mortensen

11

使用记事本创建一个文本文档并复制/粘贴以下内容:

rmdir /s/q "%temp%"
mkdir "%temp%"

选择 保存 并输入文件名:

delete_temp.bat

文件类型选 All files,然后点击 保存 按钮。

这适用于任何类型的账户(管理员或标准用户)。只需运行它!

我在这个示例中使用了一个临时变量,但你也可以使用任何其他变量!PS:仅适用于 Windows 操作系统!


一个相当简单和清晰的解决方案 - Carlos Liu

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