【问题标题】:Batch: Truncate String before saving to variable批处理:在保存到变量之前截断字符串
【发布时间】:2015-02-14 10:50:27
【问题描述】:

也许这是一个简单的问题。我想制作一个输出已安装、已使用和可用 RAM 的小批量脚本。用过的内存没问题,我就是用的

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

它以 MB 为单位输出空闲 RAM。但是当我使用

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

它以 kB 为单位输出总 RAM,这会创建一个 > 32 位的字符串,在我的情况下为 8441917440。有没有办法在将其保存到变量之前截断它?就像截断最后三位数或六位数一样?否则我将无法用它来计算。

谢谢!!

【问题讨论】:

  • 我的机器将 freePhysicalMemory 输出为 KB,totalPhysicalMemory 输出为字节

标签: string batch-file truncate cut


【解决方案1】:

这是一个在一次调用 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

批处理和 PowerShell 之间的上下文切换相当慢。使用混合批处理/JScript 更快。

我写了hybrid JScript/batch utility called JEVAL.BAT that makes it convenient to incorporate JScript within any batch file

使用 JEVAL.BAT 的以下脚本的速度大约是使用 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

【讨论】:

    【解决方案2】:

    您可以使用 PowerShell 对大于 32 位的数字进行数学运算。

    @echo off
    setlocal enabledelayedexpansion
    
    :: Get free physical memory, measured in KB
    for /f "tokens=2 delims==" %%A in ('wmic os get freephysicalmemory /value ^| find "="') do set free_physical_memory_kb=%%A
    
    :: Get total physical memory, measured in B
    for /f "tokens=2 delims==" %%A in ('wmic computersystem get totalphysicalmemory /value ^| find "="') do set total_physical_memory_b=%%A
    
    :: Batch can't do math with numbers larger than 429496728, but PowerShell can
    :: The huge number can still be stored in a batch variable because it gets treated
    :: as a string until calculations are done with it
    for /f %%A in ('powershell !total_physical_memory_b!/1024') do set total_physical_memory_kb=%%A
    
    :: Convert the KB variables to MB
    :: Batch can only do integer math, so the numbers will be rounded down
    set /a free_physical_memory_mb=%free_physical_memory_kb%/1024
    set /a total_physical_memory_mb=%total_physical_memory_kb%/1024
    
    :: Get the percentage available (again, using PowerShell because batch can only do integer math)
    for /f %%A in ('powershell !free_physical_memory_mb!/!total_physical_memory_mb!*100') do set free_percent=%%A
    
    echo Free memory: %free_physical_memory_mb% MB
    echo Total memory: %total_physical_memory_mb% MB
    echo Percentage free: %free_percent%%%
    
    pause
    

    【讨论】:

    • +1,但有一些不准确之处。 “:: Batch 无法对大于 429496728 的数字进行数学运算” - 嗯? Batch 使用带符号的 32 位整数,因此有效范围在 -2147483648 和 2147483647 之间。“:: Batch 只能进行整数数学运算,因此数字将向下舍入” - 不,数字将被截断为整数,而不是四舍五入.为什么不在 PowerShell 中进行所有计算?
    • @dbenham - 我不知道我从哪里得到那个号码;我试图说 4294967295,但看起来我以某种方式删除了 2^32 末尾的 6,然后从 that 中减去了 1。完全忘记了它是签名的,所以无论如何我都会错的。四舍五入到整数和截断之间有区别吗?
    【解决方案3】:

    如果您可以忍受增量,则删除最后 3 (6) 位数字很容易:

    set  x=8441917440
    echo cut last 3 digits: %x:~0,-3%
    echo cut last 6 digits: %x:~0,-6%
    REM or to cut it in the variable:
    set x=%x:~0,-6%
    echo cut last 6 digits: %x%
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 1970-01-01
      • 2021-10-05
      • 2017-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多