max07
max07

Reputation: 141

Batch File returning folder size and delete content if greater than 50gb

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

Answers (3)

pieh-ejdsch
pieh-ejdsch

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

aschipfl
aschipfl

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

abelenky
abelenky

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?


This works for me:

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

Related Questions