【问题标题】:How to delete *.* excluding some extensions?如何删除 *.* 不包括某些扩展?
【发布时间】:2012-02-24 02:06:27
【问题描述】:

我正在尝试在 Windows 上创建一个批处理文件,用于删除当前目录中的所有文件,但不包括 4 个文件扩展名(log、sdb、SDK、bat)。

我在 Windows 上尝试过 Forfiles 命令,但这会删除我当前文件夹中的所有内容(甚至是 bat 文件)。我的命令是:

@ECHO OFF
FORFILES /M *.* /C "cmd /c IF NOT @ext=="sdb" (IF NOT @ext=="sbk" (IF NOT @ext=="log" (IF NOT @ext=="bat" DEL @FILE)))" /Q

我怎样才能让它工作?

【问题讨论】:

    标签: batch-file cmd forfiles


    【解决方案1】:
    • 内部引号必须用\ 转义
    • 您可能需要IF /I(不区分大小写)选项
    • 您应该使用@ISDIR 排除目录
    • DEL /Q 选项在最后一个报价之后,应该在最后一个报价之前,但不是必需的
    • 不需要括号
    • 不需要 FORFILES /M 选项,因为您的掩码是“所有文件”

    这应该可以工作

    @echo off
    forfiles /c "cmd /c if @isdir equ FALSE if /i not @ext==\"sdb\" if /i not @ext==\"sbk\" if /i not @ext==\"log\" if /i not @ext==\"bat\" del @file"
    

    但是上面写的很慢,打字肯定很多。

    以下内容更简单、更快捷。

    @echo off
    for /f "delims=" %%F in ('dir /b /a-d ^| findstr /vile ".sdb .sbk .log .bat"') do del "%%F"
    

    【讨论】:

    • 我想将选项安排为/live/vile 相比似乎太无聊了,不是吗。 :)
    • @AndriyM - 来一个,来一个……看看邪恶的生活! :)
    • @Tim - 哪种方法不适合您? forfiles 还是 for /f?我很确定两者都应该可以工作,但是当文件名中有 unicode 时 for /f 可能会失败。空格应该不是问题。
    • @Tim 仅使用 FOR /F 循环测试了第二个版本,它适用于文件或文件夹名称中的空格(在 Windows 7 上)。
    • 如果我有多个文件夹,我想从所有这些子文件夹中删除文件,除了我想要的扩展名?
    【解决方案2】:

    如果您可以使用ROBOCOPY

    @ECHO OFF
    MKDIR temporary_pit
    ROBOCOPY . temporary_pit /XF *.sdb *.sbk *.log *.bat /MOV >NUL
    RMDIR /S /Q temporary_pit
    

    也就是说,您正在创建一个临时子目录,将要删除的文件移动到其中(这很快,因为目标目录在同一个驱动器上,只有文件名被重定位,而不是文件的内容),然后删除子目录。

    【讨论】:

    • 酷!很好,您如何利用 RoboCopy 的功能。并且没有字符串处理问题。我想知道为什么你的答案没有被更多投票......
    • @pepoluan:谢谢!我认为必须为子目录提供一个唯一的名称是这种方法的一个特别弱点。另一方面,使用 ROBOCOPY 的内置 /XF + /MOV 功能的想法也是最吸引我的地方。当然,DEL * /XF files 会更好。 :) 哦,好吧。
    • 不,如果是硬盘,一个临时目录只消耗几 KB,完全值得。
    • 这对我来说仍然很慢,直到我添加了 /CREATE 选项以便在目的地创建零长度文件。这使得这个过程更快。
    • @ShekharReddy:xcopyhas an /exclude option,但是那个选项使用起来似乎不太方便,当然不如robocopy/XF方便。我自己没有尝试过,但手册确实表明它比较麻烦。
    【解决方案3】:

    另外,你可以这样做:

    @echo off
    attrib -r -s *.*
    attrib +r +s *.sdb
    attrib +r +s *.sbk
    attrib +r +s *.log
    attrib +r +s *.bat
    del *.* /S /Q
    attrib -r -s *.sdb
    attrib -r -s *.sbk
    attrib -r -s *.log
    attrib -r -s *.bat
    

    -- 马里奥

    【讨论】:

    • 或者更简单的set exclude=sdb sbk log batattrib -r -s *.*for %%e in (%exclude%) do attrib +r +s *.%%edel *.* /S /Qfor %%e in (%exclude%) do attrib -r -s *.%%e
    • 或者更简单的attrib -r -s *.* for %%e in (sdb sbk log bat) do attrib +r +s *.%%e del *.* /S /Q attrib -r -s *.*
    【解决方案4】:
    @echo off
    setlocal EnableDelayedExpansion
    set exclude=.log.sdb.sdk.bat.
    for %%f in (*.*) do (
       if /I "%exclude%" == "!exclude:%%~Xf.=!" del "%%f"
    )
    

    【讨论】:

    • 甚至比 FINDSTR 更简单,但是由于扩展名包含 . 并且我们不想将 .b 误认为是 .bat,所以有点错误。修复:set exclude=.log.sdb.sdk.bad.!exclude:%%~Xf.=!
    【解决方案5】:
    forfiles /s /c "cmd /c (if NOT @ext==\"dqy\" del /s /q @path)" /D -14
    

    这和我能得到这个脚本一样简单。他们想保留宏文件 (.dqy),但递归删除超过 14 天的所有其他文件。

    在当前目录中运行(测试时要小心)。

    【讨论】:

      【解决方案6】:

      我遇到了这个主题,寻找一种方法来删除由病毒创建的数百个文件。 没有一个解决方案真的对我有用,所以我想出了如何从命令行来做。我只需要保留 2 个扩展名(邮件存档)。 这成功了:

      for /R %f in (*) do if not %~xf==.ex1 if not %~xf==*.ex2 del "%f"
      

      我使用 /R 进行递归工作:查看所有子文件夹。 %~xf 只查看扩展名(由于某种原因,没有它就无法工作)。 我在删除命令中使用引号“%f”来用空格覆盖 Windows 长名称(尤其是在文件夹名称中)。 同样出于某种原因,在 == 之前添加空格并添加错误会导致错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-27
        • 1970-01-01
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-11
        相关资源
        最近更新 更多