windowsbatch-filebatch-processingstring-matching

WINDOWS 2k8R2: Remove (or to do something else) on older files in the directory based on their names


I can produce directory names based on current date/time: getting these values from WMIC into environment variables to produce:

set BackDirName="%year%%month%%day%"
mkdir %BackDirName%

After running the batch for several times, I got a number of directories like:

20140901
20140908
...
20141127

And I want to keep only some newest directories, removing older ones. Here's how it may look in some abstract pseudo-PL:

rem in this PL array's items numbered starting from 1
declare var_dir_list:array of string
:start
rem listing all like 20YYMM* - I'll die before year 2100 :-)
list_dirs 20[1-9][0-9][0-1][0-9]* order:alphabetic direction:a-to-z  
    names_per_line:1 show:only-names =>var_dir_list
if number_of_lines(var_dir_list) GT 4 then
    rem deleting first directory in list
    remove_dir name:var_dir_list[1]
    rem removing first line from list
    var_dir_list=var_dir_list[2..number_of_lines(var_dir_list)]
    goto start
end if

The pseudo-code above iterates and deletes all but last (newest) 4 directories. I need to emulate this functionality using built-in Windows' batch file processors. I can't rely on creation/modification dates of these folders/files, that's why I hardcoded the date in their names.

How do I implement such functionality? (using VBscript is acceptable)


Solution

  • This code gets a list of all directories in the source directory (you'll have to specify this), sorts them by date in reverse order, skips the first four, and deletes the rest.

    @echo off
    set source_dir="C:\Where\The\Directories\Are"
    
    :: Takes a list of all directories in the source directory
    :: /a:d grabs only directories
    :: /:o-d sorts them in reverse by date (newest on top)
    :: /b gets simple filenames so that this actually works
    :: "skip=4" skips the first four listed
    :: rd /s deletes recursively
    :: /q forces the deletion without asking
    :: and the rest are deleted
    for /f "skip=4 tokens=* delims=" %%A in ('dir /a:d /o:-d /b %source_dir%') do rd /s /q %source_dir%\%%A