例如,有一个名为%pathtofolder%的变量,因为它清楚地表明它是文件夹的完整路径。

我想删除这个目录中的每一个文件和子文件夹,但不是目录本身。

但是,可能会出现类似“此文件/文件夹已被使用”的错误…当这种情况发生时,它应该继续并跳过该文件/文件夹。

这有什么命令吗?


当前回答

我尝试了其中几种方法,但没有一种能正常工作。

我在Windows命令行网站上找到了这个两步方法:

forfiles /P %pathtofolder% /M * /C "cmd /c if @isdir==FALSE del @file"

forfiles /P %pathtofolder%  /M * /C "cmd /c if @isdir==TRUE rmdir /S /Q @file"

它完全按照我需要的和OP指定的那样工作。

其他回答

Use:

del %pathtofolder%\*.*   /s /f  /q

这将删除%pathtofolder%中的所有文件和子文件夹,包括只读文件,并且不提示确认。

你可以使用这个shell脚本清理C:\Temp源代码中的文件夹和文件:

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

创建包含上述命令的批处理文件(例如delete.bat)。进入delete.bat文件所在位置,执行delete.bat命令

删除文件:

del PATH_TO_FILE

删除包含所有文件的文件夹。

rmdir /s /q PATH_TO_FOLDER

删除特定文件夹中的所有文件(不删除文件夹本身)有点复杂。Del /s *。*不能删除文件夹,但可以从所有子文件夹中删除文件。因此需要两个命令:

del /q PATH_TO_FOLDER\*.*
for /d %i in (PATH_TO_FOLDER\*.*) do @rmdir /s /q "%i"

我有以下对我有效的解决方案:

/R /D %A in (*node_modules*) do rmdir "%A" /S /Q

它从当前目录及其子文件夹中删除所有节点模块文件夹。

这与上面发布的解决方案类似,但我仍然在这里发布这个,以防有人发现它有用

在2018-06-01发布的答案中,除了foxidrive发布的单个命令行之外,没有一个真正删除%PathToFolder%中的所有文件和所有文件夹/目录。这就是为什么用一个非常简单的命令行发布一个答案来删除文件夹的所有文件和子文件夹,以及一个批处理文件,其中有一个更复杂的解决方案,解释了为什么在2018-06-01发布的所有其他答案都使用DEL和for with RD未能完全清理文件夹。


简单的单命令行解决方案,当然也可以用于批处理文件:

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

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

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

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

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

系统无法找到指定的路径。

通过使用2>nul将其重定向到设备nul,可以抑制该错误消息。

只有当前命令进程的当前目录更改到指定目录成功,即指定目录根本不存在,才会执行下一条命令RD。

带有/Q和/S选项的RD命令会悄悄删除一个目录及其所有子目录,即使指定的目录包含隐藏属性或只读属性设置的文件或文件夹。system属性永远不会阻止删除文件或文件夹。

未删除的有:

Folders used as the current directory for any running process. The entire folder tree to such a folder cannot be deleted if a folder is used as the current directory for any running process. Files currently opened by any running process with file access permissions set on file open to prevent deletion of the file while opened by the running application/process. Such an opened file prevents also the deletion of entire folder tree to the opened file. Files/folders on which the current user has not the required (NTFS) permissions to delete the file/folder which prevents also the deletion of the folder tree to this file/folder.

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

该进程无法访问该文件,因为它正被另一个进程使用。

文件在这里是错误的术语,因为在现实中,文件夹正在被另一个进程使用,当前命令进程执行命令RD。好吧,在现实中,文件夹是文件系统的一个特殊文件,具有文件属性目录,这解释了这个错误消息。但是我不想深入讨论文件系统管理。

这个错误消息,像所有其他错误消息一样,可能因为上面写的三个原因而发生,通过用2>nul将它从句柄STDERR重定向到设备nul来抑制。

第三个命令POPD的执行与命令RD的退出值无关。

POPD从堆栈中弹出PUSHD推送的目录路径,并将当前运行命令进程的目录更改为该目录,即恢复初始的当前目录。POPD删除PUSHD在UNC文件夹路径下创建的临时驱动器号。

注意:如果初始当前目录是要清理的目录的子目录,而该目录已不存在,POPD可以静默地无法恢复初始当前目录。在这种特殊情况下,%PathToFolder%仍然是当前目录。因此,建议不要从%PathToFolder%的子目录运行上面的命令行。

One more interesting fact: I tried the command line also using a UNC path by sharing local directory C:\Temp with share name Temp and using UNC path \\%COMPUTERNAME%\Temp\CleanTest assigned to environment variable PathToFolder on Windows 7. If the current directory on running the command line is a subdirectory of a shared local folder accessed using UNC path, i.e. C:\Temp\CleanTest\Subfolder1, Subfolder1 is deleted by RD, and next POPD fails silently in making C:\Temp\CleanTest\Subfolder1 again the current directory resulting in Z:\CleanTest remaining as the current directory for the running command process. So in this very, very special case the temporary drive letter remains until the current directory is changed for example with cd /D %SystemRoot% to a local directory really existing. Unfortunately POPD does not exit with a value greater 0 if it fails to restore the initial current directory making it impossible to detect this very special error condition using just the exit code of POPD. However, it can be supposed that nobody ever runs into this very special error case as UNC paths are usually not used for accessing local files and folders.

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

推 /? 弹出 /? 路/?

使用Windows批处理文件的单行多命令解释了这里使用的操作符&&和&。


接下来让我们看看批处理文件解决方案,使用命令DEL删除%PathToFolder%中的文件,使用FOR和RD删除%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命令用于删除指定目录下的所有文件。

The option /A is necessary to process really all files including files with the hidden attribute which DEL would ignore without using option /A. The option /F is necessary to force deletion of files with the read-only attribute set. The option /Q is necessary to run a quiet deletion of multiple files without prompting the user if multiple files should be really deleted. >nul is necessary to redirect the output of the file names written to handle STDOUT to device NUL of which can't be deleted because of a file is currently opened or user has no permission to delete the file. 2>nul is necessary to redirect the error message output for each file which can't be deleted from handle STDERR to device NUL.

FOR和RD命令用于删除指定目录下的所有子目录。但是for /D没有被使用,因为在这种情况下for会忽略带有隐藏属性集的子目录。因此,For /F用于在一个单独的命令进程中运行以下命令行,该进程在后台使用%ComSpec% /c启动:

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

DIR以裸格式输出,因为/B的目录条目具有属性D,即指定目录中所有子目录的名称独立于其他属性,如没有路径的隐藏属性。2>nul用于在句柄STDERR中没有找到目录的情况下,通过DIR将错误消息输出重定向到设备nul。

重定向操作符>必须在FOR命令行上用插入字符^转义,以便在Windows命令解释器在执行FOR命令之前处理该命令行时解释为文字字符,该FOR命令在后台启动的单独命令进程中执行嵌入的dir命令行。

FOR处理为处理已启动命令进程的STDOUT而写入的捕获输出,这些输出是子目录的名称,没有路径,并且不包含在双引号中。

带有选项/F的FOR会忽略空行,因为带有选项/B的DIR不会输出空行。

FOR也会忽略以分号开头的行,分号是默认的行尾字符。目录名可以以分号开头。因此,eol=|用于将竖条字符定义为任何目录或文件的名称中都不能包含的行结束字符。

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

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

为了理解所使用的命令及其工作原理,打开命令提示窗口,在那里执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页。

戴尔/? 迪尔/? 回波/? 结束本地 /? 为/? 转到/? 如果/? 路/? 雷姆/? 设置/? 设置本地 /?