Ambushes
Ambushes

Reputation: 53

Batch file that counts the number of files in EVERY folder in a directory, and outputs results to a text file

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

Answers (4)

Aacini
Aacini

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

James Curran
James Curran

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

Squashman
Squashman

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

Jean-François Fabre
Jean-François Fabre

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

Related Questions