5

I would like to recursively delete all files with a specific extension in a batch file.

I am aware of the following command:

del /s *.ext

However, this does on Windows also delete files with other extensions like e.g. .ext1 or .ext2 . The reason for this seems to be that the 8.3 file name of such a file ends with .ext and therefore also the files with longer extensions are matched.

I am looking for a replacement to the command above that recursively deletes all files with .ext extension but keeps files with longer extensions.

FourtyTwo
  • 1,616
  • 2
  • 15
  • 43
  • 1
    Good question, and it seems only to be relevant to short extensions (like three letters): I tried with "test.tralala" and "test.tralalala" and "del /s *.tralala" only removed one file. – Dominique Jul 23 '20 at 07:06
  • Bad question. This is a programming site. Ask on https://superuser.com. –  Jul 23 '20 at 07:32
  • 3
    @Mark: I disagree. It's a piece of code that doesn't quite work as intended. It describes the actual outcome, the desired outcome and the shortest code to replicate the issue. – Stephan Jul 23 '20 at 07:41
  • 1
    It's not code at all. Its a typed command. –  Jul 23 '20 at 08:42
  • 3
    @Mark OP requires a batch-file to delete the files, he tried the _"command"_ in the batch-file and clearly did not do what OP wanted, hence this question is a valid StackOverflow question. – Gerhard Jul 23 '20 at 08:45
  • It a typed command. It is not programing. It is not interesting as it showns no knowledge of Windows. –  Jul 23 '20 at 09:23
  • 5
    @mark, what is a `batch-file` then? it is a `file`, with `batch`es of _"commands"_, launched in sequence... no? – Gerhard Jul 23 '20 at 09:42

3 Answers3

2

the where command works a bit differently (in regards to wildcards and short-names). Put a for /f loop around, and you're done. Your example would then translate to:

for /f "delims=" %%a in ('where /r . *.ext') do ECHO del "%%a"

Note: I disarmed the del command by just echoing it. Remove the ECHO after troubleshooting, when you are sure it does exactly what you want.

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • I accept this answer because it's the simplest way to solve my specific problem - Compo's answer is not relevant for my use case. +1 for both other answers anyhow, since they both add valuable information for similar problems. – FourtyTwo Jul 24 '20 at 09:31
  • @FourtyTwo, my answer is 100% relevant for all scenarios. What you mean is that you do not care about making the code robust, because you cannot envisage, in your specific case, ever having a file named `something.ext.com`, `something.ext.exe`, `something.ext.bat`, `something.ext.cmd`, `something.ext.vbs`, `something.ext.vbe`, `something.ext.js`, `something.ext.jse`, `something.ext.wsf`, `something.ext.wsh`, `something.ext.msc`, or `something.ext.AnyOtherExtensionHeldInPathExt`, anywhere within the entire tree rooted at your unspecified current directory. – Compo Jul 27 '20 at 13:36
2

This also uses where.exe, but takes account of an issue not mentioned in another answer.

The issue is that where searches append each extension listed under %PATHEXT% to your .ext glob/spec. So whilst it will delete your target files, excluding files like .ext1 and .ext2 etc. it will now include for example, *.ext.com, *.ext.exe, *.ext.bat, *.ext.cmd, *.ext.vbs, *.ext.vbe, *.ext.js, *.ext.jse, *.ext.wsf, *.ext.wsh, and *.ext.msc etc.

The fix is to simply empty the content of %PATHEXT% before issuing the command. The following method does so within the For loop parenthsized command. As that is ran in another cmd.exe instance, it will not affect the instance in which the rest of your script resides:

@For /F "Delims=" %%G In ('"(Set PATHEXT=) & "%__APPDIR__%where.exe" /F /R "C:\SourceDir" "*.ext" 2>NUL"') Do @Del /A /F %%G

Obviously, you would modify, C:\SourceDir to contain the root location you require. The other current answers, use the current directory. If you want that, change it to ., or if you want the directory base as that of your batch file, change it to %~dp0.. Please do not remove any doublequotes.


Here are some alternative method examples, (please remember to adjust the drive/path/extension as needed)

If you wish to stick with the more traditional Dir command, then you could pipe the results through the findstr.exe utility, to exclude those matching the 8.3 names:

@For /F "Delims=" %%G In ('"Dir /B /S /A:-D "C:\SourceDir\*.ext" 2> NUL | "%__APPDIR__%findstr.exe" /I /L /E ".ext""') Do @Del /A /F "%%G"

You could also use the forfiles.exe utility for the task:

@"%__APPDIR__%forfiles.exe" /P "C:\SourceDir" /S /M "*.ext" /C "\"%__APPDIR__%cmd.exe\" /C \"If @IsDir==FALSE Del /A /F @File\""

Or this excruciatingly slow WMIC.exe utility method:

@"%__APPDIR__%wbem\WMIC.exe" DataFile Where "Drive='C:' And Path Like '\\SourceDir\\%%' And Extension='ext'" Delete 1> NUL 2>&1
Compo
  • 36,585
  • 5
  • 27
  • 39
  • If interested parties wish to see a demonstration of the `where` issue I mentioned, create a two line batch file **1.** `@MD "Temporary\SubFolder"&For %%G In (.ext .ext1 .ext2 .ext.com)Do @CD.>"Temporary\madeupname%%G"&CD.>"Temporary\Subfolder\anothername%%G` **2.** `@"%__APPDIR__%where.exe" /R "Temporary" "*.ext"&Pause`. When you run it, you should clearly see the `.ext.com` files listed. This means, without undefining/emptying `%PATHEXT%`, you would effectively be deleting executable files with names containing the string `.ext`. _(Don't forget to remove the Temporary directory afterwards)_. – Compo Jul 23 '20 at 13:56
1

Stephans answer is the shorter version, but you can use findstr's regex as well to match that the end of the name should be .ext

for /f "delims=" %%i in ('dir /b /s ^| findstr /IRC:"\.ext$"') do echo del "%%~i"
Gerhard
  • 22,678
  • 7
  • 27
  • 43