Delete all files older than 365 days, but exclude certain folders

7,509

Solution 1

You can try this script but it will work only if %%~tA in your regional settings is returning the file date using YMD format. If not, the comparison will not work as expected.

@Echo Off
setlocal enabledelayedexpansion

for /r %%A in (*.cfg;*.dat;*.hdr) do (
  set p=%%~pA
  set numeric=no
  if "!p:~1,1!"=="0" set numeric=yes
  if "!p:~1,1!"=="1" set numeric=yes
  if "!p:~1,1!"=="2" set numeric=yes
  if "!p:~1,1!"=="3" set numeric=yes
  if "!p:~1,1!"=="4" set numeric=yes
  if "!p:~1,1!"=="5" set numeric=yes
  if "!p:~1,1!"=="6" set numeric=yes
  if "!p:~1,1!"=="7" set numeric=yes
  if "!p:~1,1!"=="8" set numeric=yes
  if "!p:~1,1!"=="9" set numeric=yes

  if !numeric!==yes (
    if "%%~tA" LSS "2012-11-08" (
      del %%A
    )
  )
)

endlocal

EDIT

I think I have managed to modify the script to work the way you want. I had to get rid of /r switch and call a subroutine recursively or the blacklist would not work properly. The blacklist should be stored in blacklist.txt file in the same directory where the script resides. The file should contain full paths to excluded folders without quotes:

D:\excluded folder1
D:\excluded folder2
D:\included folder\excluded folder3

For each folder that is not blacklisted a subroutine is called which searches for files based on extension and then each file's date is compared with the date given. Please test the script thoroughly. I am afraid it may break on folder names containing special characters like % or ^.

@Echo Off
call :browse D:
goto :EOF

:browse
for /d %%A in ("%~1\*") do (
  find /i "%%A" %~dp0blacklist.txt > nul
  if errorlevel 1 (
    call :delete "%%A"
    call :browse "%%A"
  ) else (
    echo SKIP %%A
  )
)
goto :EOF

:delete
for %%A in ("%~1\*.cfg" "%~1\*.dat" "%~1\*.hdr") do (
  if "%%~tA" LSS "2012-10-08" (
    echo DEL  %%A
    del "%%A"
  ) else (
    echo SAVE %%A
  )
)
goto :EOF

Solution 2

I think MBu's answer is better than mine since it doesn't rely on an external tool like Robocopy. And if the blacklisted folders list grow my Robocopy command will look ugly. Nevertheless I want to share what I have found.

You can misuse Robocopy to delete old files, filter for certain extensions and exclude multiple directories from scanning - all in one command.

md C:\TrashMe 
robocopy C:\ C:\TrashMe *.cfg *.hdr *.txt *.dat /MOVE /E /MINAGE:365 /CREATE /R:1 /W:1 /XD C:\dir1 C:\dir2 C:\TrashMe
rd C:\TrashMe

The batch will create a temporary trash folder named TrashMe.
Robocopy will than move (not copy!) all desired files (correct extension and modified time stamp older than 365 days) to that trash folder. You exclude multiple folders with the /XD switch.
The last action is to remove the trash folder containing all found old files which.

The trick is to use the /CREATE switch so robocopy will create zero-byte files instead of the actual source file. This speeds up the command move and delete part.


Robocopy command in detail

  • robocopy calls C:\Windows\System32\Robocopy.exe which is preinstalled on Windows Server 2003, Vista, 7 and 8
  • C:\ is the source folder which should be scanned
  • C:\TrashMe is the (temporary) target folder for all found files
  • *.cfg *.hdr *.txt *.dat are wildcards and will filter for certain file extensions
  • /MOVE will cut&paste all found files instead of copy&paste them
  • /E will scann all subdirectories
  • /MINAGE:365 will exclude all files which are newer than 365 days
  • /CREATE will create zero-based files instead of the original source file
  • /R:1 /W:1 is the number of retries and wait time between if file is locked and can't be deleted
  • /XD C:\dir1 C:\dir2 C:\TrashMe is my list of blacklisted folders. I had to include the TrashMe folder as well because it is placed within the source folder
Share:
7,509

Related videos on Youtube

nixda
Author by

nixda

Updated on September 18, 2022

Comments

  • nixda
    nixda over 1 year

    Edit: After @Mbu answer I realized that my first approach with leading numbers in folders as criteria to exclude isn't the right way. I decided to use a fixed list of folders to exclude.


    I want to delete certain files via batch , but exclude a given set of paths to be checked

    Example structure

    E:.
    |───MyBatchFile.cmd
    |
    ├───yes
    │   │   no.doc        | file has wrong extension
    │   │   yes.cfg
    │   │   yes.dat
    │   │   yes.hgr
    │   │
    │   └───yes
    │           yes.cfg
    │           yes.dat
    │           yes.hgr
    │
    ├───yes
    │       yes.cfg
    │       no.dat        | file is too new, modified within a year
    │       no.hgr        | file is too new, modified within a year
    │
    |───no1               | folder is on blacklist
    |       importantstuff
    │
    └───no2               | folder is on blacklist
            importantstuff
    

    The yes and no file names demonstrate which files should be deleted

    What I want

    Search all files in all folders and subfolders starting at the folder where the batch is placed. If all following conditions are true, delete the file

    1. file extension is .cfg, .dat, .hgr or .txt
    2. modified time is more than 365 days old
    3. Path is not on blacklist

    What I have tried

    Based on this question, I have:

    @echo off
    for %%i in (.cfg, .dat, .hdr, .txt) do (
      forfiles /s /m *%%i /d -365 /c "cmd /c del @path"
    )
    pause
    

    Two of three issues are solved, but how do I exclude a given set of folders.
    Like E:\no1 and E:\no2 from my example.

    • Rik
      Rik over 10 years
      What issues do you have exactly. To me the batch seems fine besides the fact you used -p E:" instead of -p E:\ .
    • Ramhound
      Ramhound over 10 years
      @nixda - Explain the output of what you tried. So we won't have to run it to test it.
    • MDT Guy
      MDT Guy over 10 years
      Why do I suspect powershell maybe the better option here?
    • nixda
      nixda over 10 years
      @MDTGuy Powershell was my first try. But the Windows 2003 server admin said, that he won't install PowerShell. Luckily Robocopy is already preinstalled :)
    • David
      David over 10 years
      o_O Who would refuse to install PowerShell??
    • nixda
      nixda over 10 years
      @David Yeah, that was pretty much my reaction too :D
  • Scott - Слава Україні
    Scott - Слава Україні over 10 years
    It might be easier to handle the top-level initial numeral requirement by doing for /d %%t in (0* 1* 2* 3* 4* 5* 6* 7* 8* 9*) do for /r %%A in (%%t\*.cfg %%t\*.dat %%t\*.hdr) do ….
  • nixda
    nixda over 10 years
    Hi MBu, thanks for your answer. Unfortunately I had to update my question. Maybe you have also an idea for excluding paths via a given blacklist?
  • sryaoperations
    sryaoperations over 10 years
    @nixda, I have edited my answer. The new script should work the way you want it.
  • sryaoperations
    sryaoperations over 10 years
    Well, Robocopy may be a better option if you have folders with names containing CMD special characters.