Page 1 of 1

Find recursively (!) all empty dirs below top folder?

Posted: 11 Sep 2018 02:22
by pstein
Assume I want to find all dirs below a certain top node folder (e.g. D:\data\logs\) which are emtpy?

"recursively" means if a dir contains only empty dirs (and no files) it should be considered as empty as well.

How can code this in a dos batch file?

Peter

Re: Find recursively (!) all empty dirs below top folder?

Posted: 11 Sep 2018 10:02
by CirothUngol
Well, if removing empty directories is what you're after as opposed to Simply locating them, then the following macro does that rather efficiently.

Code: Select all

::recursively remove all empty folders from a directory tree
SET nullDir=FOR %%# IN (1 2)DO IF %%#==2 (%\n%
	FOR /F "tokens=*" %%: IN ('DIR /AD-S/B/S !##! 2^^^>NUL ^^^|SORT/R')DO RD "%%:"^>NUL 2^>^&1%\n%
	ENDLOCAL%\n%
)ELSE SETLOCAL EnableDelayedExpansion^&SET ##=%= \Path\to\Folder =%
The code could be slightly aberrated to merely identifying them instead of removing them, but by Nature a folder with other folders in it isn't actually empty, so those will prove more difficult to identify.

Re: Find recursively (!) all empty dirs below top folder?

Posted: 23 Sep 2018 03:04
by pstein
@CirothUngol

Thank you for your suggestion.
You are right: Finally I want to remove all empty folders.
But at first I want to list them only.

Unfortunately your code produces an error:

File Not Found
')ELSE' is not recognized as an internal or external command,
operable program or batch file.

Whats wrong?

In my batch script I replaced \Path\to\Folder with the topnode folder. So alltogether my code looks like

Code: Select all

set topnode=D:\data\logs\
cd /d %topnode%
echo just listing empty folders
SET nullDir=FOR %%# IN (1 2)DO IF %%#==2 (%\n%
  FOR /F "tokens=*" %%: IN ('DIR /AD-S/B/S !##! 2^^^>NUL ^^^|SORT/R')DO echo "%%:"^>NUL 2^>^&1%\n%
   ENDLOCAL%\n%
 )ELSE SETLOCAL EnableDelayedExpansion^&SET ##=%= %topnode% =%
I wonder why you wrote the EnableDelayedExpansion statement into the else branch

Wouldn't it be suffiient to write it once at the top of the script?

Thank you
Peter

Re: Find recursively (!) all empty dirs below top folder?

Posted: 23 Sep 2018 09:56
by CirothUngol
Oops, sorry 'bout that. %nullDir% is a fancy 'macro', a small batch routine contained inside a variable so you don't have to issue a CALL command... which happens to be just about the slowest thing in batch. A more complete and useful version looks like this:

Code: Select all

@ECHO OFF
:: define a newline with line continuation 
(SET \n=^^^
%= This defines an escaped Line Feed - DO NOT ALTER =%
)

:: recursively remove all empty folders from a directory tree
SET nullDir=FOR %%# IN (1 2)DO IF %%#==2 (%\n%
	FOR /F "tokens=*" %%: IN ('DIR /AD-S/B/S !##! 2^^^>NUL ^^^|SORT/R')DO RD "%%:"^>NUL 2^>^&1%\n%
	ENDLOCAL%\n%
)ELSE SETLOCAL EnableDelayedExpansion^&SET ##=%= \Path\to\Folder =%

:: call the macro
%nullDir% %1
EXIT /B 0
SETLOCAL is issued inside the routine so the macro can be used in batch scripts that don't use DelayedExpansion. SETLOCAL is used after the ELSE statement to assure that it's the first statement executed by the routine and avoid accidentally clobbering any variables in the script that calls it (maybe it's using %##%? you never know...). Remember, SETLOCAL/ENDLOCAL is a way to keep local variables local, as opposed to global. This is all needlessly fancy, of course.

Code: Select all

@ECHO OFF
:nullDir folderName
FOR /F "tokens=*" %%: IN ('DIR /AD-S/B/S %1 2^>NUL ^| SORT/R') DO RD "%%:" >NUL 2>&1
EXIT /B 0
...is all you need, just make sure your parent folder is used for %1. It works by issuing a DIR /A(ttribute)D(irectories)-(ignore)S(ystem folders)/B(are info)/S(earch recursive) and piping it into SORT.EXE /R(everse). This assures that the 'bottom-most' folders are removed first so that nested folders are properly emptied, and conveniently RD will remove only empty folders unless the /S switch is used. Of course, any commands you wish may be used. To list the folders as they are emptied, perhaps try:

Code: Select all

@ECHO OFF
:nullDir folderName
FOR /F "tokens=*" %%: IN ('DIR /AD-S/B/S %1 2^>NUL ^| SORT/R') DO (
	RD "%%:" >NUL 2>&1
	IF NOT EXIST "%%:" ECHO %%:
)
EXIT /B 0