43} Is there a way of counting the number of files in a folder / subfolders?
First off, let's exclude the files in the subfolders from the
consideration and take the information directly from the folder listing
@echo off & setlocal enableextensions
set folder_=C:\_D\TEST
for /f "tokens=1" %%f in ('
dir "%folder_%\*.*"^|findstr /c:" File(s)"') do (
set countf_=%%f)
for /f "tokens=1" %%d in ('
dir "%folder_%\*.*"^|findstr /c:" Dir(s)"') do (
set countd_=%%d)
echo %folder_%
echo Found %countf_% files, %countd_% folders
endlocal & goto :EOF
The output might be something like
C:\_D\TEST
Found 20 files, 2 folders
Note that the above includes the . and .. inherent in every folder.
Next let's include the subfolders and actually count the number of
files and subfolders instead of extracting the information from the
folder summary. (The . and .. are excluded.)
@echo off & setlocal enableextensions
set startFolder=C:\_D
set /a countd_=0
set /a countf_=0
for /f %%f in ('dir /s /b /a:d "%startFolder%\*.*"') do set /a countd_+=1
for /f %%f in ('dir /s /b /a:-d "%startFolder%\*.*"') do set /a countf_+=1
echo Found %countf_% files, %countd_% subfolders
echo in and below "%startFolder%"
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq
Found 2801 files, 146 subfolders
in and below "C:\_D"
If you wish to count what is on C: substitute in the above (without a
backslash)
set startFolder=C:
A word of caution. This one may take quite a long while to process.
Let's not stop there, but list the files together with an ordinal
number.
@echo off & setlocal enableextensions
set startFolder=C:\_D
set /a FileCount_=0
for /f "delims=" %%f in ('
dir /s /b /a:-d /o:e "%startFolder%\*.*"') do (
call :ListOneFile "%%f")
endlocal & goto :EOF
::
:: ===========================================
:ListOneFile
set /a FileCount_+=1
call :FuncRightJustify5 %FileCount_% FileCount_
echo %FileCount_: =0% %*
goto :EOF
::
:: ===========================================
:FuncRightJustify5 arg1 arg2
setlocal enableextensions
set number_= %1
set number_=%number_:~-5%
endlocal & set "%2=%number_%" & Goto :EOF
The output might be something like
C:\_D\TEST>cmdfaq
00001 "C:\_D\HAE.BAT"
:
00017 "C:\_D\BAS\CMDFAQ2.CMD"
00018 "C:\_D\BAS\FAQPAS.PAS"
00019 "C:\_D\BAS\test & 3.txt"
00020 "C:\_D\BAS\test (4!).txt"
00021 "C:\_D\BAS\VBSFAQ.VBS"
:
02800 "C:\_D\WORD\WORDVB.TXT"
02801 "C:\_D\WORD\wordxml.xml"
The problem can also be solved with a VBS-aided script (giving the
same output as in the above)
@echo off & setlocal enableextensions
::
set topfolder_=C:\_D
::
:: Build a Visual Basic Script
set skip=
set vbs_=%temp%\tmp$$$.vbs
findstr "'%skip%VBS" "%~f0" > "%vbs_%"
::
:: Run it with Microsoft Windows Script Host Version 5.6
cscript //nologo "%vbs_%" "%topfolder_%"
::
:: Clean up
for %%f in ("%vbs_%") do if exist %%f del %%f
endlocal & goto :EOF
'
' The Visual Basic Script
'
Sub TraverseOneFolder(foldername) 'VBS
Dim fso, f, f1, fc 'VBS
Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
Set f = fso.GetFolder(foldername) 'VBS
Set fc = f.Files 'VBS
For Each f1 in fc 'VBS
i = i + 1 'VBS
Wscript.Echo PadFn(CStr(i),5), f1 'VBS
Next 'VBS
End Sub 'VBS
'
Sub TraverseManyFolders(startfoldername) 'VBS
Dim fso, f, f1, sf 'VBS
Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
Set f = fso.GetFolder(startfoldername) 'VBS
If Instr (1, Ucase(f), "RECYCLER") = 0 Then 'VBS
TraverseOneFolder(f) 'VBS
End If 'VBS
Set sf = f.SubFolders 'VBS
For Each f1 in sf 'VBS
If Instr (1, Ucase(f1), "RECYCLER") = 0 Then 'VBS
TraverseManyFolders(f1) 'VBS
End If 'VBS
Next 'VBS
End Sub 'VBS
'
Function PadFn (str, n) 'VBS
If Len(str) > n Then 'VBS
PadFn = str 'VBS
Else 'VBS
PadFn = Right(String(n-1,"0")&str,n) 'VBS
End If 'VBS
End Function 'VBS
'
' The main script
i = 0 'VBS
TraverseManyFolders(WScript.Arguments.Unnamed(0)) 'VBS
If you just wish to count the top folder change TraverseManyFolders to
TraverseOneFolder on the last line.