Reputation: 53
What I'm trying to do is make a batch file that'll recursively go into every folder and count the number of files in each folder. However, I've spent the last hour trying various things and it isn't working.
I want the output to look like: X:Y where X is the folder name and Y is the # of files in X.
setlocal EnableDelayedExpansion
set current=blank
FOR /D %%G in ("*") DO set current=%%G && call:count
:count
set count=0
for %%A in (*) do set /a count+=1
echo !current!:!count!>>"D:\User\Some\Directory\count.txt"
But this doesn't work. The output is giving the same number for each folder. The number it's outputting is the number of files in the directory itself, which I think is the problem.
Specifically, if I'm in C:\User\Example
and it has three folders, A, B, and C, I want the number of files in C:\User\Example\A
and so on, but it's giving me the number of files in C:\User\Example
. Hope that makes sense.
Note: In my use case, the folders will not contain sub-directories.
Upvotes: 4
Views: 11281
Reputation: 67216
The answers to this question looks like a collection of different ways to do the same thing! Here it is another one:
@echo off
setlocal EnableDelayedExpansion
for /F "tokens=1,2 delims=\" %%a in ('findstr /M /S "^" *.*') do (
if "%%b" neq "" (
set "name=%%a"
set /A "count[!name: =_!]+=1"
)
)
(for /F "tokens=2,3 delims=[]=" %%a in ('set count[') do (
set "name=%%a"
echo !name:_= !:%%b
)) > count.txt
This method look complicated because the management of spaces in the folders names. If folders don't have spaces, 6 lines (and Delayed Expansion) could be removed; that is:
@echo off
setlocal
for /F "tokens=1,2 delims=\" %%a in ('findstr /M /S "^" *.*') do (
if "%%b" neq "" set /A "count[%%a]+=1"
)
(for /F "tokens=2,3 delims=[]=" %%a in ('set count[') do echo %%a:%%b) > count.txt
Upvotes: 2
Reputation: 103495
Here is a PowerShell script to handle it:
Get-ChildItem -Path . -Recurse -ErrorAction SilentlyContinue -Force
| Where-Object { $_.Attributes -eq "Directory"}
| ForEach-Object {Write-Host $_.Name, $_.GetFiles().Count }
The prints to the screen, but writing to a file is simple.
The scans all the way down. If you just want the first layer of folders, remove the "-Recurse"
The advantage is that you are doing real actions on real objects, instead of trying to trick the OS into doing things it's not really intended for, by parsing text.
Here, it should be relatively simple to figure out what this is doing, even if you have little knowledge of PowerShell (Get a list of children, from this path, which are directories, and for each of them, print it's name, and the count of files in it.)
Upvotes: 1
Reputation: 14290
A little different approach.
@echo off
FOR /D %%G in ("*") DO (
PUSHD "%%G"
FOR /F "delims=" %%H in ('dir /a-d /b * ^|find /C /V ""') DO echo %%G %%H>>"..\count.txt"
POPD
)
Upvotes: 4
Reputation: 140168
this works:
note that you have to collate set current=%%G&& call:count
or current
value is "A "
(trailing space, not that you want)
And when you scan the subdir, you have to prefix *
by your current dir
@echo off
del count.txt
setlocal EnableDelayedExpansion
set current=blank
FOR /D %%G in ("*") DO set current=%%G&& call:count
goto end
:count
set count=0
for %%A in (!current!\*) do set /a count+=1
echo !current!:!count!>>"count.txt"
:end
Upvotes: 2