Reputation: 923
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
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
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:
SET
command in batch can cause chaos.Upvotes: 1