How to Create Batch code to set each line of output into separate variables

135 views Asked by At

I use this code to set first output line into variable but can't set second or other line into another variables.

wmic memorychip get capacity

Output:

Capacity
4294967296
4294967296
8589934592
4294967296

My code:

for /f "tokens=2 delims==" %%A in ('wmic memorychip get capacity /value ^| find /i "Name="') do set capacity=%%A

echo %capacity%

Output:

4294967296

But I need some code like:

do set capacity1=%%A & capacity2=%%B & capacity3=%%C & capacity4=%%D

echo %capacity1%
echo %capacity2%
echo %capacity3%
echo %capacity4%

I need to set each line into separate variables.


I need separate variables like %capacity1% and %capacity2% etc. I'll use each value to calculate using more code.

3

There are 3 answers

2
SomethingDark On BEST ANSWER

In order to generate a collection of variables (usually called an array, but batch technically doesn't have arrays (it's complicated)), you'll have to set up a variable to keep track of a counter and increment that every time a new line is read.

In order to update and use a variable inside of the same for loop, you'll need to enable delayed expansion (see this for more information about that).

Also, because wmic outputs in UTF-16 and each line ends in \r\r\n instead of \r\n, you'll need to run each line through a second for loop.

@echo off
setlocal enabledelayedexpansion

set "capacity_counter=0"
for /f "tokens=2 delims==" %%A in ('wmic memorychip get capacity /value ^| find /I "Capacity="') do (
    for /f %%B in ("%%~A") do (
        set /a capacity_counter+=1
        set "capacity[!capacity_counter!]=%%B"
    )
)

for /L %%A in (1,1,!capacity_counter!) do echo Capacity %%A: !capacity[%%A]!
10
Stephan On

Note: there might be other memory besides "Main Memory" (System ROM on one of my systems for example, and potentially other memory types, depending on the system).

Wmic can filter for MemoryType, but apparently, this is not reliable for DDR4 (and probably above), but there is also SMBIOSMemoryType, which returns 18 for DDR, 21 for DDR2, etc., so I took an approach to check if it's "18 or above". (which means, it won't work for pre-DDR memory, but maybe it can be adapted to include them (for example above mentioned SystemROM returns a 9))

@ECHO OFF
setlocal enabledelayedexpansion

set i=0
for /f "skip=1 tokens=1,2" %%a in ('"wmic memorychip get capacity,smbiosmemorytype"') do (
  if %%b geq 18 (
    for /f "delims=" %%c in ("%%a") do (
      set /a i+=1
      set  "_mem[!i!]=%%c"
    )
  )
)
set _mem[
for /l %%i in (1,1,%i%) do echo Dimm %%i is !_mem[%%i]!.

Here's a reference table for the Memory Device Types (Thank you, Copmpo)

SMBIOSMemoryType,Value
1,Other
2,Unknown
3,DRAM
4,EDRAM
5,VRAM
6,SRAM
7,RAM
8,ROM
9,FLASH
10,EEPROM
11,FEPROM
12,EPROM
13,CDRAM
14,3DRAM
15,SDRAM
16,SGRAM
17,RDRAM
18,DDR
19,DDR2
20,DDR2 FB-DIMM
21,Reserved
22,Reserved
23,Reserved
24,DDR3
25,FBD2
26,DDR4
27,LPDDR
28,LPDDR2
29,LPDDR3
30,LPDDR4
31,Logical non-volatile device
32,HBM (High Bandwidth Memory)
33,HBM2 (High Bandwidth Memory Generation 2)
34,DDR5
35,LPDDR5
36,HBM3 (High Bandwidth Memory Generation 3)

Edit Based on the table provided by Compo, I lowered the 20 to 18 to include DDR (first version of DDRx). Any hardware below that (as Main Memory) is probably not able to run a modern Windows (wmic.exe) or is very specialized.

Note: for Consumer/Home PCs SomethingDark's answer is probably sufficient - I've got an HP Z-series workstation which lists an additional entry, so I took care of that.

0
Squashman On

Just one more way to do this. There is another option to create the array of variables. Instead of doing it inside the initial FOR commands, you can just assign all the capacity values to a single variable first. Then you can use some neat trickery with how variable expansion and command execution works in batch files. This was documented first on DosTips.com in 2015 by Aacini (Antonio).

@echo off
setlocal EnableDelayedExpansion

REM Initialize capacity variable and assing all values to a single variable
set "capacity="
for /f "tokens=2 delims==" %%A in ('wmic memorychip get capacity /value ^| find /I "Capacity="') do (
    for /f %%B in ("%%~A") do if not defined capacity (set "capacity=%%B") else (set "capacity=!capacity! %%B")
)
REM Initialize array counter
set "i=1"
REM create array variables
set "capacity!i!=%capacity: =" & set /A i+=1 & set "capacity!i!=%"
REM Display all Capacity variables that are defined
set capacity