Reputation: 1751
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.
Upvotes: 5
Views: 4327
Reputation: 38719
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
Upvotes: 2
Reputation:
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"
Upvotes: 1
Reputation: 56238
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.
Upvotes: 2