6

I'm trying to get integer of free disk space in Batch file. This is a my (very) simple code.

@echo off
wmic logicaldisk get freespace >> freespace.log
exit

But output in freespace.log file.

FreeSpace    
9772687360   
57401442304  
7346626560   
0            
0            

I need to pick integer only and summation. After summation output like this.

74520756224

I search on Google as my best but I can't find solutions. Please help me:)

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
nakorndev
  • 803
  • 2
  • 11
  • 18
  • 3
    I have no idea how to do this in batch script, a vbscript or a jscript would be very easy. – rekire Oct 28 '12 at 07:07
  • 1
    batch cannot work with numbers greater than ~2 gigabytes (unless you write your own addition routines - ridiculous amount of code and work), so you are out of luck. You really should use powershell, vbscript, or jscript. – dbenham Oct 28 '12 at 12:31
  • Since you didn’t mention WMIC as a requirement, I assume it was just included as your attempt for a solution. Unfortunately, everybody below took it as the requirement for some reason and used it in their answers. WMIC is not ideal because it has poor performance compared to the native batch interpreter. [This solution](http://stackoverflow.com/a/7304937/119540) has much better performance because it avoids all external programs. – Synetech Jul 28 '14 at 20:18
  • @Synetech - The OP is asking for the sum of the free space across all the drives, which that link does not address. If you read my prior comment you will see why this is a problem with pure batch. And WMIC took 1 second the first instantiation on my machine, 0.2 seconds thereafter. Unless this is used in a tight loop, I don't think that kind of performance is an issue. – dbenham Jul 28 '14 at 21:07

4 Answers4

4

Here is an exact solution using hybrid batch and powershell. It really should be done with pure powershell, vbscript, or jscript.

The non-intuitive use of tokens and the IF statement are to compensate for the weird interaction between FOR /F and the unicode output of WMIC.

@echo off
setlocal enableDelayedExpansion
set /a freeSpace=0
for /f "skip=1 tokens=1,2" %%A in ('wmic logicaldisk get freespace') do (
  if "%%B" neq "" for /f %%N in ('powershell !freeSpace!+%%A') do (
    set freeSpace=%%N
  )
)
echo freeSpace=%freeSpace%
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • 1
    Wow, WMIC and PowerShell in the same batch file to merely get the free space. I take it that performance is not your primary concern is it? Fancy-pants solutions like this belong on [CodeGolf](http://codegolf.stackexchange.com/) more than here where performance is desirable. – Synetech Jul 28 '14 at 20:15
1

Use below code. Try replacing the caption text with deviceid if it shows ? or blank.

@echo off
setlocal
set drive=C
set free=?
rem Note: WMIC will output unicode text
wmic logicaldisk where (caption = "%drive%:") get freespace>"%temp%\free.tmp"
for /f %%A in ('type "%temp%\free.tmp"') do (set free=%%A)
echo Free space: %free% bytes
rem if exist "%temp%\free.tmp" del "%temp%\free.tmp"
Jay
  • 4,627
  • 1
  • 21
  • 30
  • Thanks for answer. I have tried to do your answer but it does not working. It has shown "get was unexpected at this time." and then window has closed. – nakorndev Oct 28 '12 at 07:58
  • Sorry, for that. It's been fixed. – Jay Oct 28 '12 at 08:29
  • Thanks for reply. It working now but I want to summation free disk spaces of all volumes on Computer. :) – nakorndev Oct 28 '12 at 10:44
  • 2
    batch cannot work with numbers larger than ~2 gigabytes. You need to switch to powershell, vbscript, or jscript. – dbenham Oct 28 '12 at 12:32
  • @dbenham: Good point. It turns out that 64-bit version of `CMD.EXE` isn't fully 64-bit. – Jay Oct 28 '12 at 13:30
1

I second @dbenham's recommendation to switch to PowerShell (or at least VBScript or JScript). However, if you want to stick with batch and don't need exact numbers you could do something like this:

@echo off

setlocal EnableDelayedExpansion

for /f %%v in ('wmic logicaldisk get freespace ^| findstr /r "[0-9]"') do (
  set val=%%v
  set val=!val:~-6!
  set /a sum+=val
)

echo !sum!

endlocal

The line set val=!val:~-6! removes the last 6 digits from each value. That way you can calculate with Megabytes instead of Bytes, but (obviously) lose some precision, because the value is truncated (and not rounded correctly).

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
1

Here is a pure batch solution that can handle numbers greater than ~ 2G:

@echo off
setlocal EnableDelayedExpansion
set /A "SUMMEG=0" & set /A "SUMONE=0"
set /A "NUM=6" & set "ZER=000000"
for /F "tokens=2 delims==" %%F in ('
    wmic LOGICALDISK GET FreeSpace /VALUE
') do (
    for %%G in (%%F) do (
        set "ONE=%ZER%%%G"
        for /F "tokens=* delims=0" %%H in ("!ONE:~,-%NUM%!") do set "MEG=%%H"
        for /F "tokens=* delims=0" %%H in ("!ONE:~-%NUM%!") do set "ONE=%%H"
        set /A "SUMMEG+=MEG" & set /A "SUMONE+=ONE"
    )
)
if not "!SUMONE:~,-%NUM%!"=="" (set /A "SUMMEG+=!SUMONE:~,-%NUM%!")
set "SUMONE=%ZER%!SUMONE!" & set "SUMONE=!SUMONE:~-%NUM%!"
for /F "tokens=* delims=0" %%H in ("%SUMMEG%%SUMONE%") do set "FRE=%%H"
endlocal & if "%FRE%"=="" (set "FRE=0") else (set "FRE=%FRE%")
echo %FRE%
aschipfl
  • 33,626
  • 12
  • 54
  • 99