Search code examples
stringbatch-filetruncatecut

Batch: Truncate String before saving to variable


maybe it's a simple question. I want to make a small batch script that outputs installed, used and free RAM. Used RAM is no problem, I just use

 for /f "skip=1" %%a in ('wmic os get freephysicalmemory') do ( 

and it outputs the free RAM in MB. But when I use

for /f "skip=1" %%p in ('wmic computersystem get totalphysicalmemory') do ( 

it outputs the total RAM in kB, which creates a string > 32 Bit, in my case 8441917440. Is there a way to truncate this before saving it into a variable? Like cutoff the last three or six digits? Otherwise I won't be able to calculate with it.

Thanks!!


Solution

  • Here is a script that performs all the computations in one call to PowerShell:

    @echo off
    setlocal
    
    :: Get free physical memory, measured in KB
    for /f "skip=1" %%A in ('wmic os get freephysicalmemory') do for %%B in (%%A) do set free_KB=%%B
    
    :: Get total physical memory, measured in B
    for /f "skip=1" %%A in ('wmic computersystem get totalphysicalmemory') do for %%B in (%%A) do set total_B=%%B
    
    :: Compute values in MB
    for /f "tokens=1-3" %%A in (
      'powershell -command "& {[int]$total=%total_B%/1MB;[int]$free=%free_KB%/1KB;$used=$total-$free;echo $total' '$used' '$free}"'
    ) do (
      set total_MB=%%A
      set used_MB=%%B
      set free_MB=%%C
    )
    
    :: Print the results
    echo Total: %total_MB% MB
    echo  Used: %used_MB% MB
    echo  Free: %free_MB% MB
    

    The context switching between batch and PowerShell is fairly slow. It is faster to use hybrid batch/JScript.

    I have written a hybrid JScript/batch utility called JEVAL.BAT that makes it convenient to incorporate JScript within any batch file.

    The following script using JEVAL.BAT is about twice as fast as using PowerShell:

    @echo off
    setlocal
    
    :: Get free physical memory, measured in KB
    for /f "skip=1" %%A in ('wmic os get freephysicalmemory') do for %%B in (%%A) do set free_KB=%%B
    
    :: Get total physical memory, measured in B
    for /f "skip=1" %%A in ('wmic computersystem get totalphysicalmemory') do for %%B in (%%A) do set total_B=%%B
    
    :: Compute values in MB
    for /f "tokens=1-3" %%A in (
      'jeval "total=Math.round(%total_B%/1024/1024);free=Math.round(%free_KB%/1024);total+' '+(total-free)+' '+free"'
    ) do (
      set total_MB=%%A
      set used_MB=%%B
      set free_MB=%%C
    )
    
    :: Print the results
    echo Total: %total_MB% MB
    echo  Used: %used_MB% MB
    echo  Free: %free_MB% MB