【问题标题】:(Batch) How to recursively delete all files/folders in a directory except those with a leading .?(批处理)如何递归删除目录中除以.开头的文件/文件夹之外的所有文件/文件夹?
【发布时间】:2018-05-14 08:29:29
【问题描述】:

我有一个目录,src。我想递归删除其所有内容,但名称以. 开头的文件(.gitignore,...)和文件夹(.git.vscode,...)除外。在子目录中匹配该模式既没有必要也没有害处。

在批处理文件中执行此操作的最简洁方法是什么?

【问题讨论】:

  • 如果在非. 目录中存在. 文件或目录会怎样?
  • 就我而言,无论哪种方式都不重要。我不相信任何这样的文件可以存在于我的环境中。我想保存会更好。
  • 到目前为止你尝试了什么,你卡在哪里了?检查使用模式.*...
  • 倒置,基本上。 for /f %%i in ('dir /b /s /a ".*"') do echo %%i 获取到我要排除的文件,但不知道如何排除。

标签: windows batch-file command-line pattern-matching


【解决方案1】:
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"

:: step 1 : delete all files NOT starting "."

FOR /f "tokens=1*delims=" %%a IN (
 'dir /s /b /a-d "%sourcedir%\*" '
 ) DO (
 ECHO %%~nxa|FINDSTR /b /L "." >nul
 IF ERRORLEVEL 1 ECHO(DEL "%%a"
)

:: step 2 : delete all directories NOT starting "."

FOR /f "tokens=1*delims=" %%a IN (
 'dir /s /b /ad "%sourcedir%\*" ^|sort /r'
 ) DO (
 ECHO %%~nxa|FINDSTR /b /L "." >nul
 IF ERRORLEVEL 1 ECHO(RD "%%a"
)
GOTO :EOF

您需要更改sourcedir 的设置以适应您的情况。

所需的 DEL 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(DEL更改为DEL即可真正删除文件。

所需的 RD 命令仅用于测试目的ECHOed。 验证命令正确后,将ECHO(RD更改为RD即可真正删除目录。

对于整个子树中的每个文件名,查看它是否以. 开头,如果不是则将errorlevel 设置为非0,然后删除该文件。

完成此操作后,对 directorynames 重复该操作,但对找到的名称进行反向排序,以便任何目录的子目录名将出现在 directoryname 之前。 尝试删除带有rd 的目录 - 如果它包含文件或子目录(隐含地以. 开头),它将保留。将2>nul 附加到rd 行以抑制错误消息(目录无法删除,因为它仍然包含文件/子目录)

【讨论】:

  • 为了我的目的,只需要删除dir 中的/s,但这很好用。谢谢!
【解决方案2】:

尝试排除带有前导点的文件夹(基于每个文件夹):

for /f "tokens=*eol=." %%A in ('dir /B /AD') do Echo=%%A

这不会影响在其他位置包含点的文件夹名称。

一个相对较慢的变体递归所有文件夹并使用 findstr 过滤所有包含\. 的文件夹,两个字符都需要用反斜杠转义

for /r /D %%A in (*) do @echo %%A|findstr /V "\\\."

【讨论】: