【问题标题】:delete some files in a sub-subfolder using batch script使用批处理脚本删除子文件夹中的一些文件
【发布时间】:2014-08-26 08:39:25
【问题描述】:

我需要一个批处理脚本来删除给定文件夹的子子文件夹中的所有文件,但两个文件除外。 我有一组可以在其中找到文件的子文件夹的名称set sf=(sf0 sf1) 这些子文件夹嵌套在给定路径下方的某处,例如

<givenPath>\something\anything\sf0
<givenPath>\whatever\sf1

我现在喜欢在那些子文件夹中删除除 2 之外的所有文件。

&lt;givenPath&gt; 中的所有其他文件和子文件夹必须保持不变。

我发现这可以通过以下方式实现:

for /R "%somePath%" %%D in (*.*) do (
    if /I not "%%D"=="dontDelete.file" (
        if /I not "%%D"=="hasToStay.file" (
             echo del /S /Q "%somePath%\%%D"
        )
    )
)

我现在的问题是让%some_path% 指向正确的子文件夹,如上所述。

如何做到这一点? 还是我完全错了,有更好的方法吗?

【问题讨论】:

  • 应该相对简单——真正的问题是要准确处理要留下的文件。如果您有一个要留下的文件名列表,以及另一个文件应该保留的目录,那么如果完整的目录名包含一个按要求命名的目录,您是否希望这些文件保留,或者只有那是“叶子”的名字?即,...\sf0\something\leaveme 应该保留还是消失?
  • 恕我直言,问题是要获取要删除的文件的句柄。要保留的文件的句柄是例如*\sf0\dontDelet.file。可以很容易地创建所有可能保留的文件的列表,如@MC-ND 的答案所示。
  • @guo,实际上,准确地说,我的答案中的代码搜索所有文件并用它们构建一个列表,但过滤检索到的列表不包括应该保留的文件夹/文件。
  • @MC-ND 非常感谢!我检查了您的解决方案,它在特殊文件夹中按预期工作,但不幸的是它也会删除非特殊文件夹中的所有文件。如果您可以将其修改为仅删除特殊文件夹中的非特殊文件,而不是其他任何内容,那将是我正在寻找的答案。

标签: windows file batch-file delete-file


【解决方案1】:

这将分两步完成

首先,生成一个完整的文件夹列表(在给定路径下)。此文件夹列表被过滤为不包含“特殊”文件夹。对于其余文件夹,所有文件都将被删除。

接下来,枚举所有剩余的文件(这是第一步的原因,如果没有必要不处理文件,只处理文件夹,所以第二个列表更短)。过滤此列表以排除“特殊”文件夹下的任何“特殊”文件。剩余文件被删除。

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem configure starting path
    set "givenPath=%cd%"

    rem list of folders that need a special test
    set "specialFolders="sf0" "sf1""

    rem list of files to keep inside special folders
    set "specialFiles="dontDelete.file" "hasToStay.file""

    rem a temporary file will be needed
    set "tempFile=%temp%\%~nx0.%random%.tmp"

    rem STEP 1 - remove all files from non special folders

        rem prepare temporary file to filter the list of folders
        (for %%a in (%specialFolders%) do echo \%%~a) > "%tempFile%"

        rem remove all files from not special folders
        for /f "delims=" %%a in ('
            dir /ad /s /b "%givenPath%" ^| findstr /i /v /e /l /g:"%tempFile%"
        ') do echo del /f /q "%%~fa\*"

    rem STEP 2 - Delete all non special files from special folders

        rem generate a temporay file to filter the list of files
        (for %%a in (%specialFolders%) do for %%b in (%specialFiles%) do echo \%%~a\%%~b) > "%tempFile%"

        rem remove any file not matching the special folder/files
        for /f "delims=" %%a in ('
            dir /a-d /s /b "%givenPath%" ^| findstr /i /v /e /l /g:"%tempFile%"
        ') do echo del /f /q "%%~fa"

    rem remove temporary file
    del /q "%tempFile%" >nul 

可以删除第一步,结果是一样的,但不是对非特殊文件夹执行del操作,而是对其中的每个文件执行del操作。

删除操作仅回显到控制台。如果输出正确,则删除del 命令前缀的echo

这个echo 测试命令使第二步找到所有在第一步中没有被删除的文件(echo)。如果不删除第一步中的echo,第二步会更快,因为它需要处理的文件更少。

已编辑以适应 cmets - 因为只有特殊文件夹中的非特殊文件应该被删除

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem configure starting path
    set "givenPath=%cd%"

    rem list of folders that need a special test
    set "specialFolders="sf0" "sf1""

    rem list of files to keep inside special folders
    set "specialFiles="dontDelete.file" "hasToStay.file""

    rem temporary files will be needed
    set "folderFilter=%temp%\%~nx0.%random%.1.tmp"
    set "fileFilter=%temp%\%~nx0.%random%.2.tmp"

    rem prepare temporary file to filter the list of folders
    (for %%a in (%specialFolders%) do echo \\%%~a\\[^^\\]*) > "%folderFilter%"

    rem prepare temporary file to filter the list of files
    (for %%a in (%specialFiles%) do echo \%%~a) > "%fileFilter%"

    rem Search all files, filter and delete
    for /f "delims=" %%a in ('
        dir /s /b /a-d "%givenPath%" 
        ^| findstr /i /e /r /g:"%folderFilter%"
        ^| findstr /i /e /l /v /g:"%fileFilter%"
    ') do echo del /f /q "%%~fa"

    rem remove temporary files
    del /q "%folderFilter%" > nul 
    del /q "%fileFilter%"   > nul

检索完整的文件列表 (dir /s),从中删除任何不在特殊文件夹中的内容(findstr 使用 folderFilter),然后从剩余的文件列表中删除特殊文件(findstr 使用 fileFilter) .列表中的任何内容都将被删除

与前面的代码一样,del 操作仅回显到控制台。如果输出正确,请删除echo 以删除文件。

【讨论】:

  • 对于最后一个 for 循环也可以处理路径中带有空格的文件,必须添加 delims 选项:
    for /f "delims=" %%a in ( '.
  • @guo,已更新。你当然是对的。我已经将它包含在第一个代码中,但我忘记包含在第二个代码中。
【解决方案2】:

您可以递归搜索文件名并删除文件。

我没有删除子目录,因为你的问题不清楚,如果你想保留目录。

除“file1”和“file2”两个文件外,所有目录中的所有文件都将被删除,目录将保留。如果要删除目录,请删除保留目录的第一个 if 循环。

批处理文件:

@echo off

rem set your two file names in these variables
set file1="a.txt"
set file2="b.txt"

for /f "delims=" %%a in ('dir /s /b *.*') do (
    if exist %%~sa\NUL (
            echo It is a directory, not deleted: %%~sa
        ) else if "%%~nxa" == %file1% (
            echo Not deleted : %file1%
        ) else if "%%~nxa" == %file2% (
            echo Not deleted : %file2%
        ) else (
            del /s /q "%%a"
        )
)

【讨论】: