I am attempting to purge a public directory, so when an item is older than 30 days it should be deleted. I have a batch file setup with the following command:
forfiles /p "C:\PATH\USERS\PATH\" /s /m *.* /c "cmd /c Del @path /q" /d -30
This works great. However, the issue is, that it only deletes the items within the folders within the path.
Example: C:\PATH\USERS\PATH\HelloWorld\file.text
is over 30 days old. But the command only deletes file.text
, not the folder.
Would I have to check to see if the folder is empty and then delete the folder with another command?
The command line you are using is quite dangerous (I just copied it here and reordered the switches):
forfiles /S /D -30 /P "C:\PATH\USERS\PATH\" /M "*.*" /C "cmd /C del /Q @path"
Because forfiles
returns both files and directories. Supposing there is a directory called container
that matches the search criteria (last modified 30 days ago or earlier), the executed del
command line is del "C:\PATH\USERS\PATH\container" /Q
, which deletes all files in there, even those not fulfilling the search criteria (note that del \folder
behaves like del \folder\*
).
To solve this issue, you need to filter for file or directories, like this:
forfiles /S /D -30 /P "C:\PATH\USERS\PATH" /M "*" /C "cmd /C if @isdir==FALSE del @path"
I also changed the file mask from *.*
to *
, because forfiles
, opposed to all internal commands, does not match files with no extension in case *.*
is given. In addition I removed the trailing \
from the path, because otherwise, forfiles
raises an error: ERROR: The directory name is invalid.
.
But now for something completely different -- the answer to your actual question:
Since forfiles /S
will return a directory before it returns its sub-items, it does not make sense do check whether the directory is empty or not in the same command line, you need to do that later.
For that purpose, you can either use a second forfiles
loop like this (also checking their last modification dates, if you like; otherwise, remove the /D -30
portion):
forfiles /S /D -30 /P "C:\PATH\USERS\PATH" /M "*" /C "cmd /C if @isdir==TRUE rd @path 2> nul"
Or alternatively, if the directory modification dates are not relevant, you can use a for /D
loop, which is also faster:
for /D %%I in ("C:\PATH\USERS\PATH\*") do rd "%%~fI" 2> nul
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With