Reputation: 141
I am trying to write a batch script, which will first return the sum of multiple folder locations and if these are greater than 50GB, delete the content.
I was googling around and still don't know how to return the size of a folder (in GB).
Can anyone help`?
Upvotes: 0
Views: 2210
Reputation: 206
with robocoby Output and erase
The code was reworked.
@echo off
setlocal
prompt $g$s
rem set size= 150.0 m
rem usage -> see SUB :Fsize
set size= 50.0 g
call :createTMP
set /a _N=0
:Listing
rem list Folder List size and delete
for /D %%F in (
D:\1?
D:\80
D:\2014-*
D:\a
) do (
if exist %%F if /i NOT "%~0"==":Listing" (
set /a _N+=1
call mklink /j "%%empty.link.tmp%%\%%_N%%" "%%~F"
) else call :delall "%%~F"
)
rem --- END SETTINGS ---
if :SUB==only (
:createTMP
set "empty.tmp=%temp%\empty_%time::=%"
set "empty.link.tmp=%temp%\link_%time::=%"
md "%empty.tmp%"
md "%empty.link.tmp%"
exit /b
)
if /i "%~0"==":Listing" (
:deltmp
for /d %%D in (
"%empty.link.tmp%\*"
"%empty.link.tmp%"
"%empty.tmp%"
) do rd "%%~D"
exit /b
)
:Listsize
call :Fsize "%size%" size.max
for /f "skip=2tokens=6*" %%a in ('
robocopy /L /purge /njh "%empty.tmp%" "%empty.link.tmp%" /nfl /ndl ^|find " 0 "
') do call :Fsize "%%b" size.out deci.mal pre
if NOT %size.out% lss %size.max% (
echo Folders: %deci.mal% %pre% ^> %size%
call :Listing
)else echo Folders %deci.mal% %pre% ^< %size% &call :deltmp
exit/b
:Fsize "512.0 k" [VAR1-floating point [VAR2-to display only [VAR3-prefix]]]
rem to use with output of robocopy
rem set with decimal minimum 1/1 max b =1024
rem set with decimal minimum 1/10 max k =.9 rounded + 102.3 bytes (+ 10 %)
rem decimal minimum 1/100 max m =.99 rounded + 10.23 KiB (+ 1 %)
rem decimal minimum 1/1000 max g =.999 rounded + 1.023 MiB (+ 0,1 %)
rem 500.0 b -> 500 bytes
rem 200.5 k -> 200,5 KiB
rem 350.04 m -> 350,04 MiB
rem 1.001 g -> 1,001 GiB
rem VAR1 size.out - Binary prefix and number to floating point
rem VAR2 deci.mal - Reverse the calculation part to display only
rem VAR3 pre.fix - Reverse the calculation to add prefix
set/a p=-1,TC=10000
for %%N in (b k m g t p)Do set /a "p+=1,%%N=p"
for /f "tokens=1-3delims=. " %%A in ("%~1 0 b")Do (
set/a"pre.fix=TC*(%%C+1) + %%A"
set "deci.mal=%%A.%%B"
setlocal enabledelayedexpansion
set "FS=!pre.fix!.%%B"
for /f "tokens=1,2" %%S in ("!FS! !deci.mal!")Do (
endlocal
if NOT "%~2"=="" (set "%~2=%%S")else set "size.out=%%S"
if NOT "%~3"=="" set "%~3=%%T"
)
)
set/ax=pre.fix/TC-1
for %%s in (b k m g t p)Do 2>nul set/a"N/=(%%s-x)"||^
if NOT "%~4"=="" (set "%~4=%%s")else set "pre.fix=%%s"
exit /b
:delall
rem be carfully - this will erase all Data !
rem 1st with option /L only list this Files
rem without /L will erase all Data
:@echo off
setlocal
set "T=%temp%\DF%time::=%"
md "%T%" ||exit /b 1
:Delete
if "%~1" equ "" goto :end
robocopy /L /fp /purge /ns /np /njh /njs "%T%" "%~dp1\" "%~nx1"
shift
goto :Delete
:end
rd "%T%"
exit /b 0
Upvotes: 0
Reputation: 34909
The size of a folder can be derived by dir /S
(see the summary at the very bottom of the output, which contains the total amount of bytes occupied by all sub-items). This can be extracted like this:
set "PREVB="
for /F "skip=2 tokens=3" %%B in ('
dir /S /-C "\path\to\folder"
') do (
call set "BYTES=%%PREVB%%"
set "PREVB=%%B"
)
But be careful: do not treat this number as an integer (by set /A
or if EQU
/GTR
/...), because cmd
supports signed 32-bit integers only, which is easily exceeded by folder sizes.
To check against 50 GB you might split the resulting number, like:
rem // Split huge number into GB and ones:
set "BYTES_GIGA=%BYTES:~,-9%"
set "BYTES_ONES=%BYTES:~-9%"
rem // Ensure GB part to be non-empty:
if not defined BYTES_GIGA set "BYTES_GIGA=0"
rem // Remove leading zeroes from ones:
set /A "BYTES_ONES=1%BYTES_ONES%%%1000000000"
Then you can round the GB number up, if you wish:
if %BYTES_ONES% GTR 0 set /A "BYTES_GIGA+=1"
Finally, check the GB number whether or not it exceeds the predefined limit:
if %BYTES_GIGA% GTR 50 (
rem // Do something, perhaps delete the entire folder:
rmdir /S /Q "\path\to\folder"
)
Upvotes: 1
Reputation: 64682
Seems to me that dir /s /-c
returns a final block:
Total Files Listed:
51 File(s) 88492332 bytes
14 Dir(s) 112224022528 bytes free
And you just need to parse out that value (88492332
).
Can you provide more explicit detail about what code you have, and why it isn't working?
GetSize.bat
for /F "delims=:" %%a in ('dir /-c /s ^| findstr /N /C:"Total Files Listed"') do set SKIP=%%a
for /F "tokens=3" %%a in ('dir /-c /s ^| more +%SKIP%') do (set FOLDER_SIZE=%%a & goto :end)
:end
echo Final Folder Size is %FOLDER_SIZE%
Upvotes: 0