• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3711
  • Last Modified:

Batch file to list subfolders and their sizes

I have a server with a lot of folders in d:\files.  I'm wondering if there's a way via batch file to query that folder for a subfolder listing but also get the total size of each of those subfolders and export that to a text file.

For example:  say d:\files has 9 subfolders.  The script would need to query d:\files and list those 9 subfolders (and only those 9, not the entire tree) and then list the total data size for each of those 9 subfolders.  That info is then saved to a text file.

Possible?
0
annexit
Asked:
annexit
  • 7
  • 5
  • 3
2 Solutions
 
knightEknightCommented:
do a google search on tail.exe and download it to d:\files (or anywhere in your path).  Then do this:

d:
cd d:\files
for /f %%D in ('dir/ad/b') do @echo %%D: >> d:\files\list.txt  &  dir/s %%D | find "File(s)" | tail -n 1 >> d:\files\list.txt
0
 
knightEknightCommented:
... the code above is meant to be run as a batch file.  You can run it as a stand-alone command instead but you will need to use a single percent symbol instead of double -- e.g.  %D  instead of  %%D  every where you see it.
0
 
annexitAuthor Commented:
I'm testing this on my workstation on the c:\temp folder.  I've modified your code to look like this:

f %%D in ('dir/ad/b') do @echo %%c: >> c:\temp\list.txt  &  dir/s %%D | find "File(s)" | tail -n 1 >> c:\temp\list.txt

I get these errors at the prompt:

C:\Temp>for /F %D in ('dir/ad/b') do @echo %c:    1>>c:\temp\list.txt  & dir/s %
D   | find "File(s)"   | tail -n 1  1>>c:\temp\list.txt
TAIL: can't open 1
TAIL: can't open 1
File Not Found

C:\Temp>pause
Press any key to continue . . .

This is the list.txt file contents:
%c:  
%c:

Thoughts?
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
annexitAuthor Commented:
I should note that TAIL.EXE is located in the c:\temp directory, along with this batch file and the outputted list.txt file.
0
 
knightEknightCommented:
This should all be on one line - I changed your %c to %D:

for /F %D in ('dir/ad/b') do @echo %D:    1>>c:\temp\list.txt  & dir/s %D   |  find "File(s)"  |  tail -n 1  1>>c:\temp\list.txt


0
 
knightEknightCommented:
(you should delete list.txt first)
0
 
knightEknightCommented:
... and of course, if you are going to run it in a batch file, you need to double the percent symbols:

del c:\temp\list.txt
for /F %%D in ('dir/ad/b') do @echo %%D:    1>>c:\temp\list.txt  & dir/s %%D   |  find "File(s)"  |  tail -n 1  1>>c:\temp\list.txt


0
 
annexitAuthor Commented:
Same error:
C:\Temp>del c:\temp\list.txt
Could Not Find c:\temp\list.txt
C:\Temp>for /F %D in ('dir/ad/b') do @echo %D:       1>>c:\temp\list.txt  & dir/
s %D     | find "File(s)"    | tail -n 1   1>>c:\temp\list.txt
TAIL: can't open 1
TAIL: can't open 1
File Not Found
C:\Temp>pause
Press any key to continue . . .
0
 
knightEknightCommented:
your version of tail.exe must not be the same as the one I am using.

some things to try ...

|  tail --lines=1   1>>c:\temp\list.txt
 |  tail -n 1   >>c:\temp\list.txt

the -n 1 parameter tells tail.exe (my version) to only output one line.  I'm guessing your version must have a different flag for this.  What does the help screen suggest?   tail.exe --help
0
 
ChristopherDunnCommented:
If you didn't want to use another application, you could just overwrite the variable with a for loop and that would always yield the last line.

This is pretty much the same as knightEknight's solution with a small change to eliminate the need for tail.

It works perfectly fine, but I can't get it not to echo "File not found" for each empty subdirectory. Do you know how to fix that knight?
@echo OFF
setlocal enabledelayedexpansion
set rootdir=D:\temp
 
IF EXIST "%rootdir%\list.txt" DEL "%rootdir%\list.txt"
Echo Building list %rootdir%\list.txt...
 
For /f "tokens=*" %%D in ('dir %rootdir%\ /ad /b') do (
  set size=
  For /f "tokens=* usebackq" %%S in (`dir /s "%rootdir%\%%D"^|Find "File(s)"`) do set size=%%S
  IF "!size!"=="" set size=No Files Found
  Echo %%D: !size! >>%rootdir%\list.txt
)
Echo Complete. Press Any key to exit
Pause>nul
goto :eof

Open in new window

0
 
knightEknightCommented:
Without testing, this might eliminate the "File not Found" messages:
For /f "tokens=* usebackq" %%S in ('dir /s "%rootdir%\%%D" 2^>nul ^|Find "File(s)"') do set size=%%S
0
 
annexitAuthor Commented:
The "File not Found" message is OK, that isn't a big issue.  I tested it and it seems fine otherwise, with the exception that if the root folder has spaces in it the script bombs out.  Any way to add quotes in there somewhere to avoid this?
0
 
ChristopherDunnCommented:
Try this script. I also modified it to make the output very nice and readable. The "File not founds" were fixed thanks to knight (I was forgetting that pesky caret).
Sample Output=========================================
Contents of D:\Desktop 
 
Adobe CS3 ....................................... 247 File(s)    551,220,005 bytes 
dosUSBboot ...................................... 17 File(s)     4,370,843 bytes 
HEAT Notes and SQL .............................. 8 File(s)      123,102 bytes 
Icon Archive .................................... 15 File(s)     20,548 bytes 
MCDST ........................................... 107 File(s)    815,502,553 bytes 
Microsoft Certifications ........................ 3 File(s)      144,687 bytes 
Screen Cap ...................................... 5 File(s)      302,909 bytes 
 
 
 
listfiles.bat=========================================
@echo OFF
setlocal enabledelayedexpansion
set rootdir=D:\Desktop
set listfile=D:\Desktop\list.txt
 
IF EXIST "%listfile%" DEL "%listfile%"
 
Echo Building list of %rootdir%,
Echo and logging to %listfile%...
Echo.
 
Echo Contents of %rootdir% >>"%listfile%"
Echo. >>"%listfile%"
 
For /f "tokens=* usebackq" %%D in (`dir "%rootdir%\" /ad /b`) do (
  Echo Reading %%D...
  set size=
  For /f "tokens=1-4 usebackq delims= " %%a in (`dir /s "%rootdir%\%%D" 2^>nul ^| Find "File(s)"`) do (
    set files=%%a %%b
    set size=%%c %%d
  )
  IF "!files!"=="" set files=0 File^(s^)
  IF "!size!"=="" set size=0 Bytes
  set bufferedname=%%D ...
  For /L %%N in (1,1,45) do IF "!bufferedname:~48,1!"=="" (set bufferedname=!bufferedname!.)
  set bufferedfiles=!files!
  For /L %%N in (1,1,15) do IF "!bufferedfiles:~14,1!"=="" (set bufferedfiles=!bufferedfiles! )
  Echo !bufferedname! !bufferedfiles!!size! >>"%listfile%"
)
Echo.
Echo Complete. Press Any key to exit.
Pause>nul
goto :eof

Open in new window

0
 
annexitAuthor Commented:
It works perfectly!  Thanks guys!
0
 
ChristopherDunnCommented:
You're welcome!

If you wanted to right justify the file sizes (so you can more easily see which folders are bigger) use the code below.

Have a great day,

-Chris
Sample Output=========================================
Contents of D:\Desktop 
 
Adobe CS3 ....................................... 247 File(s) ................ 551,220,005 bytes 
dosUSBboot ...................................... 17 File(s) ................... 4,370,843 bytes 
HEAT Notes and SQL .............................. 8 File(s) ...................... 123,102 bytes 
Icon Archive .................................... 15 File(s) ...................... 20,548 bytes 
MCDST ........................................... 107 File(s) ................ 815,502,553 bytes 
Microsoft Certifications ........................ 3 File(s) ...................... 144,687 bytes 
Screen Cap ...................................... 5 File(s) ...................... 302,909 bytes 
 
 
listfiles.bat=========================================
@echo OFF
setlocal enabledelayedexpansion
set rootdir=D:\Desktop
set listfile=D:\Desktop\list.txt
 
IF EXIST "%listfile%" DEL "%listfile%"
 
Echo Building list of %rootdir%,
Echo and logging to %listfile%...
Echo.
 
Echo Contents of %rootdir% >>"%listfile%"
Echo. >>"%listfile%"
 
For /f "tokens=* usebackq" %%D in (`dir "%rootdir%\" /ad /b`) do (
  Echo Reading %%D...
  set size=
  For /f "tokens=1-4 usebackq delims= " %%a in (`dir /s "%rootdir%\%%D" 2^>nul ^| Find "File(s)"`) do (
    set files=%%a %%b
    set size=%%c %%d
  )
  IF "!files!"=="" set files=0 File^(s^)
  IF "!size!"=="" set size=0 Bytes
  set bufferedname=%%D ...
  For /L %%N in (1,1,45) do IF "!bufferedname:~48,1!"=="" (set bufferedname=!bufferedname!.)
  set bufferedfiles=!files! .
  For /L %%N in (1,1,21) do IF "!bufferedfiles:~20,1!"=="" (set bufferedfiles=!bufferedfiles!.)
  set bufferedsize=. !size!
  For /L %%N in (1,1,25) do IF "!bufferedsize:~24,1!"=="" (set bufferedsize=.!bufferedsize!)
  Echo !bufferedname! !bufferedfiles!!bufferedsize!>>"%listfile%"
)
Echo.
Echo Complete. Press Any key to exit.
Pause>nul
goto :eof

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 7
  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now