11

I'm trying to make a batch file on Windows for deleting all the files in the current directory but excluding 4 file extensions (log, sdb, SDK, bat).

I have tried the Forfiles command on Windows but this delete everything on my current folder (even the bat file). My command is:

@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

How can I make it work?

double-beep
  • 5,031
  • 17
  • 33
  • 41
Francisco Chavez
  • 111
  • 1
  • 1
  • 3

6 Answers6

13
  • internal quotes must be escaped with \
  • you probably want IF /I (case insensitive) option
  • you should use @ISDIR to exclude directories
  • DEL /Q option was after last quote, should be before last quote, but it isn't needed
  • parentheses are not needed
  • FORFILES /M option isn't needed since your mask is "all files"

This should work

@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"

But the above is very slow, and it sure is a lot to type.

The following is much simpler and faster.

@echo off
for /f "delims=" %%F in ('dir /b /a-d ^| findstr /vile ".sdb .sbk .log .bat"') do del "%%F"
Squashman
  • 13,649
  • 5
  • 27
  • 36
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • 4
    I guess arranging the options as `/live` seemed too boring compared to `/vile`, didn't it. :) – Andriy M Feb 24 '12 at 10:49
  • 9
    @AndriyM - Come one, come all... see vile evil live! :) – dbenham Feb 24 '12 at 16:51
  • @Tim - Which method is not working for you? forfiles or for /f? I'm pretty sure both should work, though for /f can fail when there is unicode in the file name. Spaces should not be a problem. – dbenham Jul 17 '13 at 23:32
  • @Tim Tested just the 2nd version with the `FOR /F` loop and it works with whitespace in file or folder names (on Windows 7). – Andreas Jul 18 '13 at 05:47
  • 1
    What if I have multiple folders inside and I want to delete files from all those sub-folders except the extensions I wanted? – Swanand Aug 13 '14 at 11:18
  • 2nd version doesn't work for me for filenames with spaces. Win7 – john c. j. Dec 22 '17 at 15:31
  • @johnc.j., I added the `DELIMS` option to the `FOR /F` code. It will work with spaces in file names now. – Squashman Dec 22 '17 at 21:59
10

If ROBOCOPY is available to you:

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

That is, you are creating a temporary subdirectory, moving the files that are to be deleted to it (which is fast because, as the destination directory is on the same drive, only file names are relocated, not the files' contents), then deleting the subdirectory.

Andriy M
  • 76,112
  • 17
  • 94
  • 154
  • Cool! Nice how you leverage RoboCopy's features. And no string processing problems. I wonder why your answer is not voted more... – pepoluan Feb 26 '14 at 05:15
  • @pepoluan: Thanks! I think the necessity to come up with a unique name for the subdirectory is a particularly weak point of this method. On the other hand, the idea of using ROBOCOPY's built-in /XF + /MOV functionality was what best appealed to me too. Of course, `DEL * /XF files` would have been much nicer. :) Oh well. – Andriy M Feb 26 '14 at 06:43
  • Naah, a temporary dir consumes just several KB if hard disk, _totally_ worth it. – pepoluan Feb 26 '14 at 07:35
  • This was still slow for me, until I added the /CREATE option so that zero-length files were created at the destination. That made the process MUCH quicker. – paulH Nov 01 '16 at 11:53
  • is there a similar way using xcopy? – Shekhar Reddy May 10 '21 at 20:58
  • 1
    @ShekharReddy: `xcopy` [has an `/exclude` option](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/xcopy), but that option doesn't seem very convenient to use, certainly not as convenient as `robocopy`'s `/XF`. I haven't tried it myself but the manual does suggest it to be quite a bother in comparison. – Andriy M May 11 '21 at 14:49
5

Also, you can do something like this:

@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

-- Mario

  • 1
    Or the simpler `set exclude=sdb sbk log bat` `attrib -r -s *.*` `for %%e in (%exclude%) do attrib +r +s *.%%e` `del *.* /S /Q` `for %%e in (%exclude%) do attrib -r -s *.%%e` – Aacini Feb 25 '12 at 04:01
  • 1
    Or the even simpler `attrib -r -s *.*` `for %%e in (sdb sbk log bat) do attrib +r +s *.%%e` `del *.* /S /Q` `attrib -r -s *.*` – Aacini Feb 26 '12 at 02:05
3
@echo off
setlocal EnableDelayedExpansion
set exclude=.log.sdb.sdk.bat.
for %%f in (*.*) do (
   if /I "%exclude%" == "!exclude:%%~Xf.=!" del "%%f"
)
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Even simpler then FINDSTR, but a little bugged since extension includes `.` and also we don't want to mistake `.b` for `.bat`. Fix: `set exclude=.log.sdb.sdk.bad.` and `!exclude:%%~Xf.=!` – dbenham Feb 24 '12 at 04:11
2
forfiles /s /c "cmd /c (if NOT @ext==\"dqy\" del /s /q @path)" /D -14

This is about as simple as I could get this script. They wanted to keep the macro files (.dqy) but recursively delete everything else older than 14 days.

Runs in the current directory (be careful when testing).

Community
  • 1
  • 1
-1

I ran across this topic searching for a way to delete hundres of files created by a virus. Non of the solutions really worked for me, so I figured out how to do it from a command line. I needed only to keep 2 extensions (mail archive). This did the trick:

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

I use the /R to work recursive: look in all subfolders. The %~xf looks at the extension only (for some reason it didn't work without it). I use the quotes "%f" at the delete command to cover the windows long names with spaces (especially in folder names). Also for some reason, adding spaces before and behing the == gave errors.

Vasch
  • 1