Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch file that keeps the 7 latest files in a folder

Can anyone help me create a batch file? Basically, my goal is to create a batch file that will keep the LATEST 7 .txt files (in other words, the newest) in the folder and subsequently delete the rest. That's IF there are more than 7 files in the folder.

The problem I'm having right now is the fact that the batch file that I have created deletes most of the files because their date is from a month or two or so. I want to keep the latest 7 files at all times no matter how old they are.

So this is what I have -

@echo off

setlocal enableextensions

rem ********************************************************************************
rem *******************************  LOCAL VARIABLES  ******************************
rem ********************************************************************************

SET TargetDirectory="C:\TEMP\test"

SET No_of_fles_to_keep=7

SET count=0 

set cnt=0

rem ********************************************************************************

cd /d %TargetDirectory%

REM timeout /T 500

 for %%x in (*) do set /a count+=1

 for %%A in (*.bat) do set /a cnt+=1

cd /d %TargetDirectory%

REM timeout /T 500

IF %count% gtr %No_of_fles_to_keep% forfiles -p %TargetDirectory% -s -m "*.txt" -d -%No_of_fles_to_keep% -c "cmd /c del @path"

echo %count% 

echo File count = %cnt% 

Any help is appreciated.

like image 401
Knowledge42 Avatar asked Nov 13 '12 19:11

Knowledge42


People also ask

What does %% mean in batch file?

Represents a replaceable parameter. Use a single percent sign ( % ) to carry out the for command at the command prompt. Use double percent signs ( %% ) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %a, %b, or %c. ( <set> )

What is Z in batch file?

The ~z modifier returns the size of the file which is referenced by the FOR 's meta variable. For it to work the meta variable ( %%a ) must point to an existing file and the file must accessible from the current directory. If %%a is an absolute path to the file (e.g. C:\MyFile.

What does %1 do in batch file?

When used in a command line, script, or batch file, %1 is used to represent a variable or matched string. For example, in a Microsoft batch file, %1 can print what is entered after the batch file name.

What does F do in batch?

FOR /F processing of a command consists of reading the output from the command one line at a time and then breaking the line up into individual items of data or 'tokens'. The DO command is then executed with the parameter(s) set to the token(s) found.


2 Answers

You can use DIR with /O-D to list the text files in descending timestamp order. FOR /F allows you to iterate over each file. SET /A is used to keep track of how many files have been listed so far. Now comes the tricky part.

Within a code block you normally need to use delayed expansion to work with the value of a variable that was set earlier in the same block. But delayed expansion can cause problems in a FOR loop if the FOR variable value contains !, and ! is valid in file names. I get around the problem by using SET /A to intentionally divide by 0 when the 7th file name has been read. This raises an error that causes the conditional code to execute that undefines the KEEP variable. From that point on, all remaining files are deleted.

@echo off
setlocal
set /a cnt=0
set "keep=7"
for /f "eol=: delims=" %%F in ('dir /b /o-d /a-d *.txt') do (
  if defined keep (
    2>nul set /a "cnt+=1, 1/(keep-cnt)" || set "keep="
  ) else del "%%F"
)

Update

Oh my goodness, I just realized there is a trivial solution. Just use the FOR /F SKIP option to ignore the first 7 entries after sorting by last modified date, descending.

for /f "skip=7 eol=: delims=" %%F in ('dir /b /o-d /a-d *.txt') do @del "%%F"

You don't even need a batch file. Just change %% to % if run from the command prompt.

like image 54
dbenham Avatar answered Sep 19 '22 12:09

dbenham


The Batch file below use a simpler approach. It use findstr /N "^" command to number each file, then it just compare each number to keep first seven files and delete the rest...

@echo off
for /f "tokens=1* delims=:" %%a in ('dir /b /o-d *.txt ^| findstr /N "^"') do (
   if %%a gtr 7 del "%%b"
)

Antonio

like image 37
Aacini Avatar answered Sep 21 '22 12:09

Aacini