Batch File To Display Directory Size

℡╲_俬逩灬. 提交于 2019-12-07 11:17:23

问题


Hi guys just wondering if u can help me modify this script that ive been playing around with, i cant get it to accept wildcard charcters '*'

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

Its in a batch file called dirsize and is called like so

dirsize c:\folder

I want it to check folder sizes for me, this one here is an example, the cache in firefox

dirsize C:\users\%username%\AppData\Local\Mozilla\Firefox\*.default\Cache

Returns the value 0

But if I go

dirsize C:\users\%username%\AppData\Local\Mozilla\Firefox\sr1znnb4.default\Cache

It works and I get the value 55322 returned.. Help me please? Thank you in advance kind people


回答1:


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).




回答2:


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.




回答3:


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)




回答4:


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:"



回答5:


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



回答6:


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


来源:https://stackoverflow.com/questions/759481/batch-file-to-display-directory-size

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