hisoka21
hisoka21

Reputation: 923

How to Delete All files But Excluding Specific Files (Batch File)

I know there are questions here like this before but in my case there are special conditions in specifying the files to be excluded in the "delete" operation.

Filename examples:

A_001.xml
A_002.xml
B_001.xml
B_002.xml
B_003.xml
C_009.xml
D_002.xml

The files above are in one directory and I need to delete all files but retain one copy of each file with the highest counter in filename which are A_002.xm, B_003.xml, C_009.xml and D_002.xml.

Is this possible? I'm new in batch file creation so please help me.. I already know how to delete files and even exclude a specific file extension but I don't know what to do in this scenario.

Upvotes: 1

Views: 4531

Answers (2)

joojaa
joojaa

Reputation: 4434

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set newprefix=_
for /F %%a in ('dir /on /b /a-d *.xml') do (
for /F "delims=_" %%i in ("%%a") do (
   IF NOT *%%i*==*!newprefix!* (
   for /F %%q in ('dir /on /b /a-d %%i*.xml') do set lastitem=%%q
   attrib +r !lastitem!  > NUL
   del /s /q %%i*.xml 1>NUL 2>NUL 
   attrib -r !lastitem!  > NUL
   set newprefix=%%i
   )
)
)

For each prefix of xml file, lists all the files with the prefix in question to get the last one in the list. Then mark the last one read only. Delete all with given pattern except read only. Reset read only flag and do over for next prefix.

Upvotes: 1

Magoo
Magoo

Reputation: 80023

@ECHO OFF

SETLOCAL enabledelayedexpansion
::
:: establish target directory
:: initialise PREFIX to a name that's invalid in a filename
::
SET target=.
SET prefix=:
FOR /f "tokens=1*delims=_" %%i IN (
 'dir /b/a-d/o-n "%target%\*_*.xml'
 ) DO (
IF !prefix!==%%i ECHO DEL "%target%\%%i_%%j"
SET prefix=%%i
)

This solution relies on the presence of "_" in the names of the *xml files in the target directory. I tested it on some dummy files in my batch-development directory, hence I used . for the current directory

The DIR command produces a list of the files in the target directory that match the pattern *_*.xml The/b switch means filename only, /a-d means no directory names, even if they match and /o-n means in the reverse order of name Therefore, the names will appear with the highest numeric value of the part after _ first.

The FOR reads this output and assigns the prefix to %%i and the remainder of the filename to %%j Since prefix is initialised to an invalid-in-filenames character, it cannot possibly match %%i for the first file encountered, so the DEL will not be executed. The last-encountered prefix will then be stored. Only if the next filename has a matching prefix will the DEL be executed

Note that I've inserted the ECHO keyword before the DEL. This is a safety device in case of error. The PROPOSED DEL operation will be reported to the screen, not EXECUTED. Once you're satisfied that the batch is correct, remove the ECHO and the delete operation will proceed.

Point to be observed:

  • Some editors are quite cavalier about stripping or retaining trailing spaces. Normally, this is harmless but trailing spaces on a SET command in batch can cause chaos.

Upvotes: 1

Related Questions