1

I have some files that I would like to sort through and keep the newest file. I cannot do it by file attributes date modified or created, which I could do no problem.

Here is the naming convention of the files. FileABC_YYYYMMDD.txt

  • FileABC_20190201.txt
  • FileABC_20190125.txt
  • FileABC_20190118.txt
  • FileABC_20190111.txt
  • FileABC_20190104.txt

You can see that the date stamp is in the filename itself. These files are generated weekly. So I'd like to have a batch file loop through them and delete all but most currently dated file. I have really searched for how to do this best and I'm not finding much so I need ideas. I prefer a pure cmd solution but I'm open to powershell solutions as well.


What I am trying on my own is to parse out the date with...

@echo off
setlocal enabledelayedexpansion
for /f "tokens=* delims= " %%G IN ('dir/b /a-d "C:\Users\thomas.maus\Documents\Tom\dev\Test Batch Files\dev\sortbyFileDateName\FileABC_*.txt"') do (

            set fileName=%%G 
            Set theDate=!fileName:~8,8!
            echo !theDate!


)

Then I want to take those dates somehow from the results of the loop and do something like

if "%theDate%" GEQ "*****not sure what to put here*****" (
    del *all the old files, also not sure what to put here*
)  
shadow2020
  • 1,315
  • 1
  • 8
  • 30
  • The files you've provided are already in date order, newest first, and given the names you've allocated to them are sortable alphabetically, meaning that the newest will always be listed first or last depending upon the sort order. – Compo Feb 14 '19 at 00:54
  • I am not trying to order or sort them really. I just want to delete all but the most current file. I parsed out the dates so I could try and do some math to get the greatest date and then use some sort of logic to delete anything older than the newest. – shadow2020 Feb 14 '19 at 00:55
  • You cannot do math on a text string, what you can do is split the names at the common delimiter sort the files on the date portion and delete them in sorted or reverse sorted order all except for one! – Compo Feb 14 '19 at 00:59
  • 1
    There are many existing posts here that should be able to give you a start. Try these , for example: https://stackoverflow.com/q/54657806/62576 and https://stackoverflow.com/q/44057048/62576 – Ken White Feb 14 '19 at 00:59
  • Could the part `FileABC` contain a character `_` on its own? – aschipfl Feb 14 '19 at 09:38

4 Answers4

3

How about this?

@echo off
for /f "skip=1" %%i in ('dir /o-n /b *.txt') do del %%i

If you just want to test it (see what it would delete) first, do:

@echo off
for /f "skip=1" %%i in ('dir /o-n /b *.txt') do echo %%i
spongyryno
  • 446
  • 2
  • 12
2

If you do not care about the file dates but only the dates in the file names, you could do the following, given that the part FileABC is always the same and does not contain any _ on its own:

pushd "C:\Users\thomas.maus\Documents\Tom\dev\Test Batch Files\dev\sortbyFileDateName" && (
    for /F "skip=1 delims= eol=|" %%F in ('
        dir /B /A:-D "FileABC_????????.txt" ^
            ^| sort /R
    ') do (
        del "%%F"
    )
    popd
)

Although sort /R does alphabetic sorting, this works because of your chosen date format, which ensures that alphabetic order equals alphanumeric one.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
1

We just loop through the files, sorted by date in decending order, then skip the first file, now being the latest:

@for /f "skip=1" %%a in ('dir /b /o-d *.txt') do @echo @del %%a

Important!

This example will only echo the delete command as a safe measure so you do not delete files you should not have. To perform the actual delete, remove @echo from the line.

To understand more about the functions we used, run the following from cmd.exe

  • for /?
  • dir /?
Gerhard
  • 22,678
  • 7
  • 27
  • 43
0

As an additional option, just in case the filename prefix changes throughout and only the _YYYYMMDD.txt remains constant, you can still peform the task using that date as it is already alphabetically sortable.

Here's an example:

@Echo Off
Set "SrcDir=%UserProfile%\Documents\Tom\dev\Test Batch Files\dev\sortbyFileDateName"
For /F "Delims==" %%A In ('Set $ 2^>Nul') Do Set "%%A="
Set "_="
For /F Delims^=^ EOL^= %%A In ('Where "%SrcDir%":*_????????.txt 2^>Nul'
) Do Set "_=%%~nA" & Call Set "$%%_:~-8%%=%%A"
If Not Defined _ Exit /B
For /F "Tokens=1* Delims==" %%A In ('Set $ 2^>Nul') Do Set "_=%%B"
For /F Delims^=^ EOL^= %%A In ('Where "%SrcDir%":*_????????.txt^|Find /V "%_%"'
) Do Del /A /F "%%A"

This uses the fact that the Set command will output variables in alphabetical order.

  • Lines 2 to 4 just define and undefine the variables we will be using.
  • Lines 5 and 6 is a single line split over two lines for readability. This will set variables using the last eight characters of the files basenames, to the value of the full filename.
  • Line 7 is included to exit the script, just in case no .txt files with a basename ending with an underscore followed by eight characters were found in the directory set at line 2.
  • Line 8 is the special one here, it outputs each variable and corresponding value in alphabetical order. The output is set to a variable, which overwrites itself until the loop ends. This means that the newest file, last one alphabetically, is held with the value of the file named with the newest date.
  • Lines 9 & 10 are once again a single line split over two for readability. This loops over all matching files in the directory again and uses the Find command to exclude outputting the one which matches that held in the variable as the file with the newest date. Each file output is simply deleted using the Del command.

Please note that this script assumes you only have a single file with each date, as you've only stated that the files are generated weekly.

Compo
  • 36,585
  • 5
  • 27
  • 39