List each subdirectory and the number of files within it using cmd.exe
I have several subdirectories that contain files, and I want to list each subdirectory and beside it the number of files (*.html
specifically) within that subdirectory. For example, I am in "C:\Users\user1\Desktop\temp"
and I want the following listing:
"C:\Users\user1\Desktop\temp\subdir1" 5 files
"C:\Users\user1\Desktop\temp\subdir2" 4 files
"C:\Users\user1\Desktop\temp\subdir2\subdir1" 7 files
I tried using this code, but it only lists the number of files in the current directory:
dir /b *.html /s 2> nul | find "" /v /c > tmp && set /p count=<tmp && del tmp && echo %count%
Solution 1:
I highly encourage you to learn PowerShell - it so much more complete and consistent as a language than batch. So here's the solution in PowerShell
Get-ChildItem -recurse -directory | foreach {$c = ((Get-ChildItem $_ -File *.html| Measure-Object).Count); write-host $_ $c}
or the shorter version
gci -recurse -directory | foreach {$c = ((gci $_ -File *.html| Measure).Count); write-host $_ $c}
This command gets the list of directories, pipes them to foreach
which iterates through them one at a time putting the name in the $_ variable. Then we list the files that match the pattern in each directory, count the result and save the count in $c
variable. Finally we write the path (still in $_
) and the count from $c
Solution 2:
This works for me (I just wrote it). I have combined two methods of isolating calls. You will note that I have broken apart searching the directories from the actual counting of files.
The first block uses for /R
and the call :label
functionality to search the directory structure and pass the directories found to a function called :CountFilesInDir
. The CountFilesInDir function uses another method to allow working with a variable while in a loop with the EnableDelayedExpansion
option.
I do this for two reasons. One, I like to break my code into functions. :) .. two, I am showing you both methods of getting a variable set while in a loop.
Last, you will note a variable before the first loop to decide what type of files you are trying to count called TypeToCount
.
@echo off
SetLocal EnableDelayedExpansion
Set TypeToCount=*.html
for /R %%d in (.) do call :CountFilesInDir "%%d" "%TypeToCount%"
EndLocal
goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::
:CountFilesInDir
::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal
Set InputPath=%~1
Set TypeToCount=%~2
pushd %InputPath%
Set FileCount=0
for /F "delims=" %%f in ('dir /a-d /b %TypeToCount% 2^>nul') do (
Set /a FileCount = !FileCount! + 1
)
echo "%InputPath:~0,-2%" %FileCount% files
popd
EndLocal
goto :EOF