Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

list empty directories

3,058 views
Skip to first unread message

beli...@aol.com

unread,
Feb 28, 2004, 9:38:33 AM2/28/04
to
From the Windows NT/XP command line, how can I list all the empty
directories (those with no files or subdirectories) on my C drive?

Marco Maier Said

unread,
Feb 28, 2004, 10:26:47 AM2/28/04
to
beli...@aol.com wrote in message
<news:3064b51d.04022...@posting.google.com> :

> From the Windows NT/XP command line, how can I list all the empty
> directories (those with no files or subdirectories) on my C drive?

@echo off
for /f "tokens=*" %%a in ('dir \ /b /s /ad') do call :sub "%%a"
goto :eof
:sub
set c=
for /f "tokens=2 skip=7" %%b in ('dir %1') do (
if not defined c set c=0 & if %%b==File^(s^) echo %1)

--
Marco

Timo Salmi

unread,
Mar 2, 2004, 2:52:14 AM3/2/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> @echo off
> for /f "tokens=*" %%a in ('dir \ /b /s /ad') do call :sub "%%a"
> goto :eof
> :sub
> set c=
> for /f "tokens=2 skip=7" %%b in ('dir %1') do (
> if not defined c set c=0 & if %%b==File^(s^) echo %1)

Interesting. I did independently the same (included). There are both
some similarieties and differences. Yours is more concise, but it
outputs a lot of "File Not Found" errors, which mine avoids. This
one will, incidentally, be question #57 in the forthcoming FAQ
update.

@echo off & setlocal enableextensions enabledelayedexpansion
for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\') do (
call :DirEmpty "%%d"
if "!empty_!"=="true" echo %%d)
endlocal & goto :EOF

@echo off & setlocal enableextensions enabledelayedexpansion
:DirEmpty
set empty_=true
dir %1 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
if !errorlevel! EQU 0 set empty_=false
dir %1 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul
if !errorlevel! EQU 0 set empty_=false
endlocal & goto :EOF

All the best, Timo

--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
Useful script files and tricks ftp://garbo.uwasa.fi/pc/link/tscmd.zip

Marco Maier Said

unread,
Mar 2, 2004, 6:35:12 PM3/2/04
to
Timo Salmi wrote in message <news:c21efe$5...@poiju.uwasa.fi> :

> Marco Maier Said <full...@yahoo.it> wrote:
>> @echo off
>> for /f "tokens=*" %%a in ('dir \ /b /s /ad') do call :sub "%%a"
>> goto :eof
>>:sub
>> set c=
>> for /f "tokens=2 skip=7" %%b in ('dir %1') do (
>> if not defined c set c=0 & if %%b==File^(s^) echo %1)
>
> Interesting. I did independently the same (included). There are both
> some similarieties and differences. Yours is more concise, but it
> outputs a lot of "File Not Found" errors


Here is another,similar,solution:

@echo off
for /r \ /d %%a in (*) do call :sub "%%a"
goto :eof
:sub
set /a n=0
for /f %%b in ('dir /b %1') do set /a n+=1
if %n%==0 echo %1

--
Marco

nospam...@ualberta.ca

unread,
Mar 2, 2004, 6:36:17 PM3/2/04
to
If you are looking to remove the empty directories, there is a freeware
program to do this available at:

http://www.jsiinc.com/SUBL/tip5500/rh5538.htm

In article <3064b51d.04022...@posting.google.com>,

Timo Salmi

unread,
Mar 3, 2004, 4:41:14 AM3/3/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> Timo Salmi wrote in message <news:c21efe$5...@poiju.uwasa.fi> :
> > Interesting. I did independently the same (included). There are both
> > some similarieties and differences. Yours is more concise, but it
> > outputs a lot of "File Not Found" errors

> Here is another,similar,solution:
> @echo off
> for /r \ /d %%a in (*) do call :sub "%%a"
> goto :eof
> :sub
> set /a n=0
> for /f %%b in ('dir /b %1') do set /a n+=1
> if %n%==0 echo %1

Your version still has the "File Not Found" problem. Thus,
unfortunately, as is, I can't include a pointer to your solution for
the time being. (I am releasing a FAQ update the next thing I do).

Marco Maier Said

unread,
Mar 3, 2004, 6:15:57 AM3/3/04
to
Timo Salmi wrote in message <news:c2497q$n...@poiju.uwasa.fi> :

> Marco Maier Said <full...@yahoo.it> wrote:
>> Timo Salmi wrote in message <news:c21efe$5...@poiju.uwasa.fi> :
>>> Interesting. I did independently the same (included). There are both
>>> some similarieties and differences. Yours is more concise, but it
>>> outputs a lot of "File Not Found" errors
>
>> Here is another,similar,solution:
>> @echo off
>> for /r \ /d %%a in (*) do call :sub "%%a"
>> goto :eof
>>:sub
>> set /a n=0
>> for /f %%b in ('dir /b %1') do set /a n+=1
>> if %n%==0 echo %1
>
> Your version still has the "File Not Found" problem. Thus,
> unfortunately, as is, I can't include a pointer to your solution for
> the time being.

What about this?

@echo off
for /r \ /d %%a in (*) do call :sub "%%a"
goto :eof
:sub
set /a n=0

for /f %%b in ('dir /b %1 2^>nul') do set /a n+=1
if %n%==0 echo %1 & goto :eof

--
Marco

Marco Maier Said

unread,
Mar 3, 2004, 6:17:41 AM3/3/04
to

Timo Salmi

unread,
Mar 3, 2004, 6:27:05 AM3/3/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> Timo Salmi wrote in message <news:c2497q$n...@poiju.uwasa.fi> :

> > Your version still has the "File Not Found" problem. Thus,

> What about this?


> @echo off
> for /r \ /d %%a in (*) do call :sub "%%a"
> goto :eof
> :sub
> set /a n=0
> for /f %%b in ('dir /b %1 2^>nul') do set /a n+=1
> if %n%==0 echo %1 & goto :eof

Now this one seems ok to me.

Marco Maier Said

unread,
Mar 3, 2004, 6:29:29 AM3/3/04
to
@echo off
for /r \ /d %%a in (*) do call :sub "%%a"
goto :eof
:sub
set /a n=0
for /f %%b in ('dir /b %1 /a-h 2^>nul') do set /a n+=1
if not %n%==0 goto :eof
for /f %%b in ('dir /b %1 /ah 2^>nul') do set /a n+=1
if %n%==0 echo %1

Marco Maier Said

unread,
Mar 3, 2004, 6:31:52 AM3/3/04
to
Timo Salmi wrote in message <news:c24fe9$5...@poiju.uwasa.fi> :

> Marco Maier Said <full...@yahoo.it> wrote:
>> Timo Salmi wrote in message <news:c2497q$n...@poiju.uwasa.fi> :
>>> Your version still has the "File Not Found" problem. Thus,
>
>> What about this?
>> @echo off
>> for /r \ /d %%a in (*) do call :sub "%%a"
>> goto :eof
>>:sub
>> set /a n=0
>> for /f %%b in ('dir /b %1 2^>nul') do set /a n+=1
>> if %n%==0 echo %1 & goto :eof
>
> Now this one seems ok to me.

It returns hidden folders with hidden files as empty,
see my last posting,I think it works.

--
Marco

Timo Salmi

unread,
Mar 3, 2004, 6:31:49 AM3/3/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> @echo off
> for /r \ /d %%a in (*) do call :sub "%%a"
set n=

> goto :eof
> :sub
> set /a n=0
> for /f %%b in ('dir /b %1 2^>nul') do set /a n+=1
> if %n%==0 echo %1

Or, alternatively, a setlocal to "clean up".

Marco Maier Said

unread,
Mar 3, 2004, 6:42:38 AM3/3/04
to
Timo Salmi wrote in message <news:c21efe$5...@poiju.uwasa.fi> :

> @echo off & setlocal enableextensions enabledelayedexpansion
> for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\') do (
> call :DirEmpty "%%d"
> if "!empty_!"=="true" echo %%d)
> endlocal & goto :EOF
>
> @echo off & setlocal enableextensions enabledelayedexpansion
> :DirEmpty
> set empty_=true
> dir %1 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
> if !errorlevel! EQU 0 set empty_=false
> dir %1 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul
> if !errorlevel! EQU 0 set empty_=false
> endlocal & goto :EOF

I tried it,it returns,wrongly, many dirs as empty,
for example: c:\windows\system32\Microsoft
--
Marco

charles

unread,
Mar 3, 2004, 9:03:43 AM3/3/04
to
On Tue, 02 Mar 2004 23:36:17 GMT, nospam...@ualberta.ca wrote:

>If you are looking to remove the empty directories, there is a freeware
>program to do this available at:
>
>http://www.jsiinc.com/SUBL/tip5500/rh5538.htm
>

The link on that page is dead (to me anyway). There is a another
freeware to do it at VirDet Labs Antivirus Center
<http://www.virdet.com/free.htm>.


Ray McCormick

unread,
Mar 3, 2004, 2:05:39 PM3/3/04
to
Another means of removing empty folders:

xxcopy %1\ /L/rsy/s/pd0/x*/q1

This was written within a batch file with the topmost folder to
have empty folders deleted passed as %1.
Additional switches can be added /oA to append to an error file,
/Fo to list the empty directories.
It uses the absolutely excellent xxcopy (www.xxcopy.com; free for
use on single computer, requires licensing for use over a
network).
Xxcopy is a versatile file management utility---boldly extended
xcopy. I use it all the time.

Ray

"charles" <som...@somewhere.org> wrote in message
news:u9pb409tt6adlbmm0...@4ax.com...

Timo Salmi

unread,
Mar 3, 2004, 5:04:40 PM3/3/04
to
Marco Maier Said <full...@yahoo.it> wrote:

C:\>cd c:\WINDOWS\system32\Microsoft

C:\WINDOWS\system32\Microsoft>dir
Volume in drive C is XPAD_C
Volume Serial Number is B821-5C43

Directory of C:\WINDOWS\system32\Microsoft

File Not Found

Marco Maier Said

unread,
Mar 3, 2004, 5:22:15 PM3/3/04
to
Timo Salmi wrote in message <news:c25kpo$8...@poiju.uwasa.fi> :

> Marco Maier Said <full...@yahoo.it> wrote:
>> Timo Salmi wrote in message <news:c21efe$5...@poiju.uwasa.fi> :
>>> @echo off & setlocal enableextensions enabledelayedexpansion
>>> for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\') do (
>>> call :DirEmpty "%%d"
>>> if "!empty_!"=="true" echo %%d)
>>> endlocal & goto :EOF
>>> @echo off & setlocal enableextensions enabledelayedexpansion
>>> :DirEmpty
>>> set empty_=true
>>> dir %1 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
>>> if !errorlevel! EQU 0 set empty_=false
>>> dir %1 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul
>>> if !errorlevel! EQU 0 set empty_=false
>>> endlocal & goto :EOF
>
>> I tried it,it returns,wrongly, many dirs as empty,
>> for example: c:\windows\system32\Microsoft
>
> C:\>cd c:\WINDOWS\system32\Microsoft
>
> C:\WINDOWS\system32\Microsoft>dir
> Volume in drive C is XPAD_C
> Volume Serial Number is B821-5C43
>
> Directory of C:\WINDOWS\system32\Microsoft
>
> File Not Found
>
> All the best, Timo


C:\WINDOWS\system32\Microsoft>dir /ah /s
Volume in drive C is OS
Volume Serial Number is 349E-A903

Directory of C:\WINDOWS\system32\Microsoft\Protect\S-1-5-18\User

30/01/2004 17.30 388 1a8fea1f-6290-4046-9ec8-277ce5f1dd21
22/10/2003 00.15 388 1b5db46f-cb21-48a5-b809-85adcbd71445
20/10/2003 23.05 388 4ce149be-ddb1-4f24-b7f2-e384124ff068
01/11/2003 15.18 388 5c0f5b3f-cf07-432a-85aa-7bbedef535e6
30/01/2004 17.30 24 Preferred
5 File(s) 1.576 bytes

Total Files Listed:
5 File(s) 1.576 bytes
0 Dir(s) 14.124.257.280 bytes free

Timo Salmi

unread,
Mar 3, 2004, 5:19:02 PM3/3/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> Timo Salmi wrote in message <news:c21efe$5...@poiju.uwasa.fi> :
> > @echo off & setlocal enableextensions enabledelayedexpansion
> > for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\') do (

Perhaps it is safest to leave out the system/hidden directories
for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d-s-h c:\') do (

> I tried it,it returns,wrongly, many dirs as empty,
> for example: c:\windows\system32\Microsoft

Yes, right. A hidden directory with hidden subdirectories. Which are
best left alone, anyway.

Timo Salmi

unread,
Mar 4, 2004, 12:33:43 AM3/4/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> Timo Salmi wrote in message <news:c25kpo$8...@poiju.uwasa.fi> :
(Various solution attempts)

It has become obvious to me that I thoroughly blew this one. The
possibility of hidden files and hidden subdiretories make the route
I took far too instable. Therefore, I'll have to withdraw my earlier
(non)solution, and start from scratch with stronger weapons:

@echo off & setlocal enableextensions

:: Build a Visual Basic Script
findstr "'VBS" "%~f0"|findstr /v "findstr" > %temp%\tmp$$$.vbs
:: Run it with Microsoft Windows Script Host Version 5.6
cscript //nologo %temp%\tmp$$$.vbs
:: Clean up
for %%f in (%temp%\tmp$$$.vbs) do if exist %%f del %%f
endlocal & goto :EOF

Function TraverseSubFolders(StartFolderName) 'VBS
Dim fso, f, f1, sf 'VBS
Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
Set f = fso.GetFolder(StartFolderName) 'VBS
Set sf = f.SubFolders 'VBS
For Each f1 in sf 'VBS
if Clng(f1.size) = 0 Then 'VBS
Wscript.Echo f1 'VBS
End If 'VBS
TraverseSubFolders(f1) 'VBS
Next 'VBS
End Function 'VBS

Function TraverseFolders(StartFolderName) 'VBS
Dim fso, f, f1, sf 'VBS
Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
If (fso.FolderExists(StartFolderName)) Then 'VBS
Set f = fso.GetFolder(StartFolderName) 'VBS
if CLng(f.size) = 0 Then 'VBS
Wscript.Echo f 'VBS
End If 'VBS
TraverseSubFolders(f) 'VBS
Else 'VBS
Wscript.Echo "Folder " & StartFolderName & " not found" 'VBS
Wscript.Quit 'VBS
End If 'VBS
End Function 'VBS

Dim StartAtFolder 'VBS
Dim WshShell 'VBS
Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
StartAtFolder = "C:\" 'VBS
TraverseFolders StartAtFolder 'VBS

Todd Vargo

unread,
Mar 4, 2004, 1:14:49 AM3/4/04
to

"Timo Salmi" <t...@UWasa.Fi> wrote:
> :: Build a Visual Basic Script
> findstr "'VBS" "%~f0"|findstr /v "findstr" > %temp%\tmp$$$.vbs

I've seen this done more than once and can not help but wonder, why search
the same file twice, when the first time is sufficient (with the proper
search string of course)?

findstr "'%=%VBS" "%~f0" > %temp%\tmp$$$.vbs

--
Todd Vargo (remove hyphen to reply by email)

Timo Salmi

unread,
Mar 4, 2004, 4:13:57 AM3/4/04
to
> > :: Build a Visual Basic Script
> > findstr "'VBS" "%~f0"|findstr /v "findstr" > %temp%\tmp$$$.vbs

> I've seen this done more than once and can not help but wonder, why search
> the same file twice, when the first time is sufficient (with the proper
> search string of course)?

There often is a neater solution. On the other hand the one above
better draws the user's attention to the need of "not finding
oneself".

> findstr "'%=%VBS" "%~f0" > %temp%\tmp$$$.vbs

Yes, of couse. That idea is covered long since, with a bit more
spoon-feeding the reader (there the language was QBASIC) as
find "'Q%skip%B"
in e.g. item #7 in

243153 Dec 27 2003 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
tsbat.zip Useful MS-DOS batch files and tricks, T.Salmi

It is impossible to poinpoint who used it first, but at least Benny
Pedersen used it quite long since in news:alt.msdos.batch

Even if not searching twice is a good, well-known point, in this one
I am much more concerned about not getting the actual task right.
The VBS solution I posted does not quite do what was asked. It finds
folder with no files in them, but the OP asked about files _and_
subfolders. The way to go, when I have the time again, is probably
to count the number of files and the immediate subfolders in a
folder, and if both zero so...

Timo Salmi

unread,
Mar 4, 2004, 5:46:34 AM3/4/04
to
In article <c26s0l$r...@poiju.uwasa.fi>, Timo Salmi <t...@UWasa.Fi> wrote:
> I am much more concerned about not getting the actual task right.
> The VBS solution I posted does not quite do what was asked. It finds
> folder with no files in them, but the OP asked about files _and_
> subfolders. The way to go, when I have the time again, is probably
> to count the number of files and the immediate subfolders in a
> folder, and if both zero so...

I know that it really is not a very good idea to go fishing with
solutions, but the cat already is out of the bag. This FAQ task
turned out to be tricker than most. Yes, one should come out only
with well-tested solutions. Nevertheless, since this one already got
a bit out of hand with the previous, non-working solutions, below is
another go at it.

Note that on a shared or system-managed computer you might get
access denied errors. If so, do not start high up the root of C:\

@echo off & setlocal enableextensions

:: Build a Visual Basic Script

findstr "'%skip%VBS" "%~f0" > %temp%\tmp$$$.vbs
:: Start from Folder (Customize, if need be)
set StartFold_=C:\_D
:: Run the VBS script with Microsoft Windows Script Host Version 5.6


cscript //nologo %temp%\tmp$$$.vbs
:: Clean up
for %%f in (%temp%\tmp$$$.vbs) do if exist %%f del %%f
endlocal & goto :EOF

Function NumberOfFilesInFolder(FolderName) 'VBS
Dim fso, f, f1, fc, CountFiles 'VBS


Set fso = CreateObject("Scripting.FileSystemObject") 'VBS

Set f = fso.GetFolder(FolderName) 'VBS
Set fc = f.Files 'VBS
CountFiles = 0 'VBS
For Each f1 in fc 'VBS
CountFiles = CountFiles + 1 'VBS
Next 'VBS
NumberOfFilesInFolder = CountFiles 'VBS
End Function 'VBS

Function NumberOfFoldersInFolder(FolderName) 'VBS
Dim fso, f, f1, fc, CountFolders 'VBS


Set fso = CreateObject("Scripting.FileSystemObject") 'VBS

Set f = fso.GetFolder(FolderName) 'VBS
Set fc = f.SubFolders 'VBS
CountFolders = 0 'VBS
For Each f1 in fc 'VBS
CountFolders = CountFolders + 1 'VBS
Next 'VBS
NumberOfFoldersInFolder = CountFolders 'VBS
End Function 'VBS

Function TraverseSubFolders(StartFolderName) 'VBS
Dim fso, f, f1, sf, nFil, nFol 'VBS


Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
Set f = fso.GetFolder(StartFolderName) 'VBS
Set sf = f.SubFolders 'VBS
For Each f1 in sf 'VBS

nFil = NumberOfFilesInFolder(f1) 'VBS
nFol = NumberOfFoldersInFolder(f1) 'VBS
if (CLng(nFil) = 0) And (CLng(nFol) = 0) Then 'VBS


Wscript.Echo f1 'VBS
End If 'VBS
TraverseSubFolders(f1) 'VBS
Next 'VBS
End Function 'VBS

Function TraverseFolders(StartFolderName) 'VBS
Dim fso, f, f1, sf, nFil, nFol 'VBS


Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
If (fso.FolderExists(StartFolderName)) Then 'VBS
Set f = fso.GetFolder(StartFolderName) 'VBS

nFil = NumberOfFilesInFolder(f) 'VBS
nFol = NumberOfFoldersInFolder(f) 'VBS
if (CLng(nFil) = 0) And (CLng(nFol) = 0) Then 'VBS


Wscript.Echo f 'VBS
End If 'VBS
TraverseSubFolders(f) 'VBS
Else 'VBS
Wscript.Echo "Folder " & StartFolderName & " not found" 'VBS
Wscript.Quit 'VBS
End If 'VBS
End Function 'VBS

Dim WshShell, StartAtFolder 'VBS


Set WshShell = WScript.CreateObject("WScript.shell") 'VBS

StartAtFolder = WshShell.ExpandEnvironmentStrings("%StartFold_%") 'VBS
TraverseFolders StartAtFolder 'VBS

Charles Dye

unread,
Mar 5, 2004, 12:59:58 AM3/5/04
to
On 28 Feb 2004 06:38:33 -0800, beli...@aol.com wrote:

>From the Windows NT/XP command line, how can I list all the empty
>directories (those with no files or subdirectories) on my C drive?

My take on this problem, using 4DOS or 4NT. (This approach will not
work in Microsoft's COMMAND.COM or CMD.EXE.) The GLOBAL command can
be used to execute a specified command in the current directory and
all its subdirectories:

global /h /i /q command....

/H causes GLOBAL to also visit subdirectories with the Hidden or
System attributes, /I allows it to continue even if the subsequent
command fails, and /Q suppresses GLOBAL's output. The @FILES
function returns the number of matching files and subdirectories:

global /h /i /q if %@files[*.*] == 0 command....

Unfortunately, @FILES will only return zero for an empty *root*
directory. In a subdirectory the count will include the . and ..
entries; in an empty subdirectory @FILES will return a value of two.
We need a way to distinguish the root directory from a subdirectory.
The _CWP variable looks ideal. I'll enclose it in double quotes in
case it contains troublesome characters:

global /h /i /q if %@files[*.*] == %@if["%_cwp" == "\",0,2] command....

The _CWD variable contains the name of the current directory:

global /h /i /q if %@files[*.*] == %@if["%_cwp" == "\",0,2] echo "%_cwd"

A few additional refinements. GLOBAL starts from the current directory,
so we need to switch to C:\ before using it. It would be polite to return
to the original directory when finished.

@echo off
pushd c:\
global /h /i /q if %@files[*.*] == %@if["%_cwp" == "\",0,2] echo "%_cwd"
popd

This little script would be more useful if it could be called with an
argument to specify the drive and directory to search. Default to C:\
if no argument was specified. If we can't change to the specified
directory, abort with a nonzero exit code:

@echo off
pushd %@if[%# == 0,c:\,%1] || quit 1
global /h /i /q if %@files[*.*] == %@if["%_cwp" == "\",0,2] echo "%_cwd"
popd

Finally, my easy assumption about the presence or absence of . and ..
entries needs to be reexamined. It is probably correct for local drives
like C:. But suppose we are searching, say, a mapped network drive? The
file server might or might not implement . and .. -- it would be safer to
check whether they are actually there. But it does seem safe to assume
that if the . entry is present, .. will be as well. We can use @FILES[[.]]
to check for the . entry:

@echo off
pushd %@if[%# == 0,c:\,%1] || quit 1
global /h /i /q if %@files[*.*] == %@if[%@files[[.]] == 1,2,0] echo "%_cwd"
popd

Four lines, seven commands, four functions, one internal variable, 132
bytes. Not bad. But I wonder whether it could be made smaller by using
FOR /R instead of GLOBAL....

--
Charles Dye ras...@highfiber.com

Dr John Stockton

unread,
Mar 5, 2004, 6:00:26 AM3/5/04
to
JRS: In article <3064b51d.04022...@posting.google.com>, seen
in news:alt.msdos.batch.nt, beli...@aol.com posted at Sat, 28 Feb 2004
06:38:33 :-

>From the Windows NT/XP command line, how can I list all the empty
>directories (those with no files or subdirectories) on my C drive?

That is one (clear) definition of emptiness; the directory is fully
empty and in principle contains no information other than that directly
associated with its own existence. It may however contain deleted
information.

But there are other definitions. One might disregard entries with
certain attributes; hidden, system, sub-directories. And one might want
to consider contents-of-contents, too.

Setting aside the distinction between overt and concealed files, ISTM
that there are three main orthogonal properties :
A: Whether the directory directly contains files
B: Whether the directory contains sub-directories
C: Whether the directory indirectly contains files

ISTM that a good general tool should scan the sub-tree and report, on a
line for each directory, properties A, B, and C; FIND methods can then
seek lines with/without A=0 etc. To simplify FIND, the tool should also
report D=A+B and E=A+C at least. F=B+C and G=A+B+C may not be needed,
since C>0 => B>0; but they are equally trivial to provide.

Note that a recursive FindFirst scan using a procedure with suitable
parameters can accumulate A, B, C for each directory very easily.

If the tool is given a string parameter coded to indicate which type(s)
of emptiness is of interest, then it can report only those, rendering
FIND unnecessary.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://jibbering.com/faq/> Jim Ley's FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

Todd Vargo

unread,
Mar 5, 2004, 7:33:16 PM3/5/04
to

<beli...@aol.com> wrote in message
news:3064b51d.04022...@posting.google.com...

> From the Windows NT/XP command line, how can I list all the empty
> directories (those with no files or subdirectories) on my C drive?

What the heck, I'll reinvent the wheel one more time too. :-)

The following batch finds all empty directories that are not hidden and
which do not have hidden files or subdirectories within.


@echo off & setlocal
for /d /r c:\ %%a in (*) do call :IsFiles "%%a"
goto :eof

:IsFiles
set HasFiles=False
for /d %%b in ("%~1\*") do goto :eof
for %%b in ("%~1\*") do set HasFiles=True
if %HasFiles%==False echo %1 has no files or subdirectories.

Timo Salmi

unread,
Mar 6, 2004, 1:10:28 AM3/6/04
to
Dr John Stockton <sp...@merlyn.demon.co.uk> wrote:
> in news:alt.msdos.batch.nt, beli...@aol.com posted
> >From the Windows NT/XP command line, how can I list all the empty
> >directories (those with no files or subdirectories) on my C drive?

> That is one (clear) definition of emptiness; the directory is fully
> empty and in principle contains no information other than that directly
> associated with its own existence. It may however contain deleted
> information.
> But there are other definitions. One might disregard entries with

From the system perspective the simplest definition is the
operational one, which coincides with your first. A directory is
empty if a straight RMDIR removes it, otherwise it is not.

One should NOT, of course go testing around with that actual method,
but that definition is what I tried to detect in my various
solutions attempts. As you will recall, I posted several versions,
which failed that definition one after another. The last one I
posted, though, has not been challenged yet. I think I'll put that
one back in the FAQ in due time.

The method is uses is counting the number of files and immediate
subdirectories (both overt and hidden) and considers a directory
empty, if both counts are zero. The command line script solution
utilizes VBS.

Timo Salmi

unread,
Mar 6, 2004, 1:40:30 AM3/6/04
to
> The following batch finds all empty directories that are not hidden and
> which do not have hidden files or subdirectories within.
> @echo off & setlocal
> for /d /r c:\ %%a in (*) do call :IsFiles "%%a"
> goto :eof

> :IsFiles
> set HasFiles=False
> for /d %%b in ("%~1\*") do goto :eof
> for %%b in ("%~1\*") do set HasFiles=True
> if %HasFiles%==False echo %1 has no files or subdirectories.

Quite inventive, but almost back to square one, because it is far
from the system's inherent definition of empty directories. That is
the most natural but also the most challenging of the definitions.

Perhaps someone can indeed come up with a straight CMD script
solution for this elusive task. In the meanwhile the only
system-compatible solution that has not (yet?) failed, needs VBS. Of
course that can be (and was) built into the CMD script, but the
solution is lengthy.

Timo Salmi

unread,
Mar 6, 2004, 4:05:41 PM3/6/04
to
foxidrive <foxi...@Shotmail.com> wrote:

> On 6 Mar 2004 08:40:30 +0200, Timo Salmi wrote:
> > Perhaps someone can indeed come up with a straight CMD script
> > solution for this elusive task.

> @echo off
> for /f "delims=" %%a in ('dir /s /b /ad') do (
> for /f "delims=" %%b in ('dir "%%a" /b /a 2^>nul ^|find /c /v ""') do (
> if "%%b"=="0" echo no files or folders - "%%a"))

Well done. Passes the few test I did. I am including into the FAQ a
Google reference to your posting.

What I missed before your posting was the usage of /a without any
attributes to display all the contents of a directory.

Timo Salmi

unread,
Mar 6, 2004, 4:41:52 PM3/6/04
to
foxidrive <foxi...@Shotmail.com> wrote:
> @echo off
> for /f "delims=" %%a in ('dir /s /b /ad') do (
> for /f "delims=" %%b in ('dir "%%a" /b /a 2^>nul ^|find /c /v ""') do (
> if "%%b"=="0" echo no files or folders - "%%a"))

Your (more concise and much better) solution also takes me back
(corrected) to what I earlier tried.

@echo off & setlocal enableextensions enabledelayedexpansion
for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\') do (

call :DirEmpty "%%d"
if "!empty_!"=="true" echo %%d)
endlocal & goto :EOF

::
:: ======================================================
:DirEmpty
set empty_=true
dir %1 /a 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul


if !errorlevel! EQU 0 set empty_=false

dir %1 /a 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul


if !errorlevel! EQU 0 set empty_=false

goto :EOF

Marco Maier Said

unread,
Mar 6, 2004, 5:24:29 PM3/6/04
to

> @echo off
> for /f "delims=" %%a in ('dir /s /b /ad') do (
> for /f "delims=" %%b in ('dir "%%a" /b /a 2^>nul ^|find /c /v ""') do (
> if "%%b"=="0" echo no files or folders - "%%a"))

Very good,but the ideal would be to list every 0 byte folder
that is not child of a 0 byte folder.


--
Marco

Marco Maier Said

unread,
Mar 6, 2004, 6:01:43 PM3/6/04
to
Marco Maier Said wrote in message <news:1muzyjjlne59j$.mms@MRC.MIR.SID.75> :

Something like this (not tested)

@echo off
if exist report.txt del report.txt


for /r \ /d %%a in (*) do call :sub "%%a"
goto :eof
:sub

findstr /r "^%~1%$" report.txt
if errorlevel 0 goto :eof
set /a n=0
for /f "tokens=*" %%a in ('dir /s /b /a %1 2^>nul') do set /a n+=%%~za
if %n%==0 echo %1 >>report.txt

--
Marco

Marco Maier Said

unread,
Mar 6, 2004, 6:03:32 PM3/6/04
to
Marco Maier Said wrote in message <news:13iqkebczoghf$.mms@MRC.MIR.SID.75> :

> findstr /r "^%~1%$" report.txt

findstr /r "^%~1$" report.txt
--
Marco

Marco Maier Said

unread,
Mar 7, 2004, 5:47:27 AM3/7/04
to
Timo Salmi wrote in message <news:c2dgj0$q...@poiju.uwasa.fi> :

> foxidrive <foxi...@Shotmail.com> wrote:
>> @echo off
>> for /f "delims=" %%a in ('dir /s /b /ad') do (
>> for /f "delims=" %%b in ('dir "%%a" /b /a 2^>nul ^|find /c /v ""') do (
>> if "%%b"=="0" echo no files or folders - "%%a"))
>
> Your (more concise and much better) solution also takes me back
> (corrected) to what I earlier tried.
>
> @echo off & setlocal enableextensions enabledelayedexpansion
> for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\') do (
> call :DirEmpty "%%d"
> if "!empty_!"=="true" echo %%d)
> endlocal & goto :EOF
> ::
> :: ======================================================
> :DirEmpty
> set empty_=true
> dir %1 /a 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
> if !errorlevel! EQU 0 set empty_=false
> dir %1 /a 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul
> if !errorlevel! EQU 0 set empty_=false
> goto :EOF
>
> All the best, Timo

The following folders (among the others) with empty subfolders are not
detected:

"c:\windows\Lhsp"
"c:\windows\msapps"
"c:\windows\Profiles"
"c:\windows\ServicePackFiles"
"c:\windows\SideBar"
"c:\windows\Sun"
"c:\windows\ime\chsime"
"c:\windows\ime\CHTIME"
"c:\windows\ime\imejp"
"c:\windows\system32\spool\prtprocs"
......
......

The following version of Foxidrive's solution gives better results:

@echo off
for /f "delims=" %%a in ('dir /s /b /ad') do (

for /f "delims=" %%b in ('dir "%%a" /b /a-d /s 2^>nul ^|find /c /v ""') do (
if "%%b"=="0" echo "%%a"))

--
Marco

Timo Salmi

unread,
Mar 7, 2004, 2:14:39 PM3/7/04
to
Marco Maier Said <full...@yahoo.it> wrote:
> Timo Salmi wrote in message <news:c2dgj0$q...@poiju.uwasa.fi> :
> > Your (more concise and much better) solution also takes me back
> > (corrected) to what I earlier tried.

> The following folders (among the others) with empty subfolders are not
> detected:
:
> "c:\windows\msapps"
:

A folder with empty subfolders is not empty.
c:\WINDOWS\msapps\msinfo is reported as empty
c:\WINDOWS\msapps is not reported (and should not)

Todd Vargo

unread,
Mar 7, 2004, 11:26:03 PM3/7/04
to

"Timo Salmi" <t...@UWasa.Fi> wrote in message
news:c2fsav$i...@poiju.uwasa.fi...

> Marco Maier Said <full...@yahoo.it> wrote:
> > Timo Salmi wrote in message <news:c2dgj0$q...@poiju.uwasa.fi> :
> > > Your (more concise and much better) solution also takes me back
> > > (corrected) to what I earlier tried.
>
> > The following folders (among the others) with empty subfolders are not
> > detected:
> :
> > "c:\windows\msapps"
> :
>
> A folder with empty subfolders is not empty.
> c:\WINDOWS\msapps\msinfo is reported as empty
> c:\WINDOWS\msapps is not reported (and should not)

Likewise, hidden/system folders ought not be reported (unless an /H switch
functionality is provided. ;-)

0 new messages