Batch File To Display Directory Size

我的未来我决定 提交于 2019-12-05 14:40:15

PowerShell makes this easy, of course:

    (gci . -Recurse | Measure-Object -Property Length -Sum).Sum

And PowerShell is already installed on Windows 7. Get on the bandwagon! :-)

Also, C:\users\%USERNAME%\AppData\ isn't a reliable way of finding AppData. Try %APPDATA% (or $env:APPDATA in PowerShell).

Ok for a starter, lets say wildcards are not well supported throughout batch files, and specially in for loops.
That's what I came up with:

DirSize.cmd "valid path"

@echo off
rem Args[1]= "Path" or "valid path with wildcard"
set _size=0
set dRaw=%~1
echo %~1|findstr "*"&& set dSource=%~dp1|| (
    set dSource=%~1\
    if not "%dRaw:~-1%"=="\" set dRaw=%dRaw%\
)
for /f "delims=" %%D in ('dir /ad /b %dRaw%') do call :DirSize "%dSource%%%~D"
set /a size=_size/1024
echo size=%size% k (%_size% bytes)
exit /b 0

:DirSize
    call :FileSize "%~1"
    for /f "delims=" %%d in ('dir /ad /b "%~1"2^>nul') do call :DirSize "%~1\%%~d"
    exit /b 0

:FileSize
    for /f "delims=" %%f in ('dir /a-d /b "%~1\"2^>nul') do for %%F in (%1\%%f) do set /a _size+=%%~zF
    exit /b 0

___Usage___
Argument: Needs to be a path (not a file) that either contain wildcards or not. Path need top be valid when typing dir path

___Notes___
This script does check for all files and sub-directories, even hidden/system ones. change the dir /a argument and add -h-s (like /ad-h-s) to remove this behaviour.

I revised the argument checking to my liking now, so I think it is usable.

I hope this helps.

You would need to wrap what you currently have in another for loop which expands the * into a series of directories.

So

@echo off
setLocal EnableDelayedExpansion
set /a sum=0
for /d %%D in (%1) do (
  FOR /R %%D %%I IN (*) DO (
    set /a value=%%~zI/1024
    set /a sum=!sum!+!value!
  )
)
echo Size is: !sum! k

might work (untested, though, but should give you the general idea)

If you have a Windows version of grep (you can find one at GNU utilities for Win32) you can do something like this:

dir /s %1 | grep --after-context=1 "Total Files Listed:"

This code will increase directory size limit up to 2,000,000 TB and will display more real size, what would be useful if the folder contains too many files.

rem SET DIR=%1
SET DIR=C:\DIR1\

IF NOT EXIST "%DIR%" (
ECHO Directory "%DIR%" does not exist.
goto END
)

setlocal EnableDelayedExpansion

set GB=
set SIZE=

set exp=000000000

FOR /R "%DIR%" %%F IN (*) DO (
set /a SIZE=!SIZE!+%%~zF
if !SIZE! geq 1!exp! (
set /a GB=!GB!+!SIZE:~0,-9!
for /f "tokens=* delims=0" %%a in ("!SIZE:~-9!") do set SIZE=%%a
)
)
if not defined SIZE set SIZE=0
if not defined GB goto EOS

FOR /L %%N IN (1,1,9) DO (
if "!SIZE:~%%N!" == "" (
set SIZE=!GB!!exp:~%%N!!SIZE!
goto EOS
)
)
:EOS

call :Divide !SIZE! 1024 SIZEKB

echo Size is: !SIZE!B (!SIZEKB!kB)

endlocal

:END
pause
exit

:Divide
set Num1=%~1
set Num2=%~2
set %3=
set Num=
set Number=
IF !Num2! EQU 0 goto :EOF
FOR /L %%N IN (0,1,18) DO (
if "!Num1:~%%N!" == "" goto :EOD
set Number=!Number!!Num1:~%%N,1!
if !Number! geq !Num2! (
  set /a quotient=!Number!/!Num2!
  set /a Number=!Number!-!quotient!*!Num2!
  if !Number! equ 0 set Number=
  set Num=!Num!!quotient!
) else (
  if defined Num set Num=!Num!0
)
)
:EOD
if not defined Num set Num=0
set %3=%Num%
goto :EOF

10x faster than doing it through FOR. With the advantage of being able to use any of the permitted parameters of the DIR command (in this case /S)

@ECHO OFF

SET folder="C:\WINDOWS"

call:timer

ECHO Processing, please wait...

CALL :folderSize size %folder% "/S"


CALL :strNumDivide sizeKb %size% 1024
CALL :strNumDivide sizeMb %sizeKb% 1024
CALL :strNumDivide sizeGb %sizeMb% 1024

CALL :formatNumber size %size%
CALL :formatNumber sizeKb %sizeKb%
CALL :formatNumber sizeMb %sizeMb%
CALL :formatNumber sizeGb %sizeGb%

ECHO.
ECHO Size of %folder%: 
ECHO.

ECHO %size% bytes
ECHO %sizeKb% Kb
ECHO %sizeMb% Mb
ECHO %sizeGb% Gb
ECHO.

pause
exit /b

:: Function to calculate the size of a directory and its subdirectories
::----------------------------------------------------------------------
:folderSize <returnVariableName> <folder> [DIR parameters]
    SetLocal EnableExtensions EnableDelayedExpansion

    SET folder=%2
    SET params=%~3

    IF NOT DEFINED folder SET folder="%CD%"

    DIR %params% /W "%folder:"=%" > %TEMP%\folderSize.tmp

    FOR /F "tokens=1 delims=:" %%x IN ('findstr /n /e ":" %TEMP%\folderSize.tmp') DO (SET line=%%x)

    IF DEFINED line (

        SET /A line = !line! + 1

        FOR /F "tokens=4 delims= " %%i IN ('findstr /n "bytes" %TEMP%\folderSize.tmp^|findstr "!line!:"') DO (SET size=%%i)
        SET size=!size:.=!

    ) ELSE (

        FOR /F "tokens=3 delims= " %%i IN ('findstr /e "bytes" %TEMP%\folderSize.tmp') DO (SET size=%%i)
        SET size=!size:.=!

    )

    DEL %TEMP%\folderSize.tmp > nul

    EndLocal & SET "%~1=%size%"

GOTO:EOF



:: Extras functions to convert between different units and to give numerical format
:: --------------------------------------------------------------------------------
:strNumDivide <returnVariableName> <stringNum> <divisor>
    SetLocal EnableExtensions EnableDelayedExpansion 

    SET strNum=%~2
    SET divisor=%~3

    SET result=
    SET number=

    IF !divisor! EQU 0 GOTO:EOF

    FOR /L %%n IN (0,1,18) DO (
        IF NOT "!strNum:~%%n!" == "" (
            SET number=!number!!strNum:~%%n,1!

            IF !number! GEQ !divisor! (
                SET /A quotient=!number! / !divisor!
                SET /A number=!number! - !quotient! * !divisor!
                IF !number! EQU 0 SET number=
                SET result=!result!!quotient!
            ) ELSE (
                IF DEFINED result SET result=!result!0
            )
        )
    )

    IF NOT DEFINED result SET "result=0"
    EndLocal & SET "%~1=%result%"

GOTO:EOF


:formatNumber <returnVariableName> <number> [separator [group size]] 
    SetLocal EnableExtensions EnableDelayedExpansion 
    SET "raw=%~2"
    SET "separator=%~3" 
    SET "group=%~4" 
    SET "answer=" 
    IF NOT DEFINED raw GOTO :EOF
    IF NOT DEFINED separator SET "separator=."
    IF NOT DEFINED group SET "group=3"

    FOR %%g IN (-%group%) DO (
        FOR /F "tokens=1,2 delims=,." %%a IN ("%raw%") DO ( 
            SET int=%%a
            SET frac=%%b

            FOR /F "delims=:" %%c IN ('^(ECHO;!int!^& Echo.NEXT LINE^)^|FindStr /O "NEXT LINE"') DO (
                SET /A length=%%c-3
            ) 

            FOR %%c IN (!length!) DO ( 
                SET radix=!raw:~%%c,1!
            )

            FOR /L %%i IN (!length!, %%g, 1) DO ( 
                SET answer=!int:~%%g!!separator!!answer! 
                SET int=!int:~0,%%g!
            ) 
        ) 
    )
    SET answer=%answer: =%
    SET answer=%answer:~0,-1%

    EndLocal & SET "%~1=%answer%%radix%%frac%" 
Goto :EOF 

Result output example: (in the example, the routine took 3 seconds to calculate the size of the C: \ WINDOWS with a size of 28GB)

Processing, please wait...

Size of "C:\WINDOWS":

30.936.389.769 bytes
30.211.318 Kb
29.503 Mb
28 Gb


Elapsed Time: 3 secs
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!