BATCH (CMD) 中 wmic 输出的自定义格式

Custom Format for wmic output in BATCH (CMD)

如何批量设置 wmic 输出的自定义格式?

在一切开始之前,我不想说我不是英语而且我的文字会很糟糕 lmao

Hello, i'm a batch beginner and i would like to make a custom output format for wmic

例子:

1# Memory Name : Corsair

2# Memory Name : Kingston

3# Memory Name : Corsair

4# Memory Name : Kingston

问题是我的代码只会显示最新的内存名称 就像我有 4 个内存芯片,但它只会显示其中一个

例子:

1# Memory Name : Corsair

但我真的不知道如何使用自定义输出格式做我想做的事

如果您需要实际代码:

wmic memorychip get manufacturer /value | findstr /r /v "^$" > manufacturer & wmic memorychip get capacity /value | findstr /r /v "^$" > capacity & set /p manufacturer=<manufacturer&set /p capacity=<capacity
set memory%manufacturer%&set memory%capacity%&del manufacturer&del capacity

echo Memory : %memorymanufacturer% %memorycapacity%

我建议您使用我的 wmiClass.bat program 而不是标准的 wmic.exe 命令。

@if (@CodeSegment == @Batch) ( @then

Show properties of a WMI class.

wmiClass [/NS:namespace] [*|class [*|property ...] [/WHERE:clause]]

  /NS:namespace     Specify the namespace, defaults to \root\cimv2.
  class             Show property names of the given class.
  class property    Show values of given properties of the class or alias.
  /WHERE:clause     Clause to select property records to process.

List names of all WMI classes
   wmiClass *

List all properties of the given class
   wmiClass Win32_LocalTime

Show values of all properties of the class
   wmiClass Win32_LocalTime *

Show specific values
   wmiClass Win32_LocalTime Year Month Day

Show values from a wmic.exe alias
   wmiClass OS LocalDateTime

Show selected records
   wmiClass Win32_Process ProcessID Name /where:"Name='cmd.exe'"

@endHelp

Developed and written by Antonio Perez Ayala

First version of this program is a modification of wmiCollection function
included in FindRepl.bat version 2.2 program released on 2014
https://www.dostips.com/forum/viewtopic.php?f=3&t=4697&p=38121#p38121

- 2022/02/21: version 1
- 2022/02/23: version 1.1: /NS option added
- 2022/02/27: version 1.3: significant code rewrite based on version 1.2 written by siberia-man
                           https://www.dostips.com/forum/viewtopic.php?p=66294#p66294
                           "*" and /WHERE options added. Auto-search for alias added
)

@echo off

if "%~1" == "" (
   for /F "skip=2 tokens=1* delims=:" %%a in ('findstr /N "^" "%~F0"') do (
      if "%%b" == "@endHelp" goto :EOF
      echo/%%b
   )
)

CScript //nologo //E:JScript "%~F0" %*
goto :EOF


@end


// http://msdn.microsoft.com/en-us/library/aa393741(v=vs.85).aspx

var args = WScript.Arguments.Unnamed,
    opts = WScript.Arguments.Named,
    wmi  = GetObject( "WinMgmts:" + (opts.Exists("NS")?opts.Item("NS"):"") ),
    clas = args.Item(0),  collection, fetch;

function enumerate (collection,fetch) {
    var r = [];
    for ( var e = new Enumerator(collection); !e.atEnd(); e.moveNext() ) {
        r.push(fetch(e.item()));
    }
    return r;
}


if ( clas == "*" ) {  // List all classes in this NameSpace; ignore properties, if any
   collection = wmi.SubclassesOf();
   fetch = function(el) { return el.Path_.Class; };

} else if ( args.length == 1 ) {  // No properties given: list all property names of given class
   collection = wmi.Get(clas).Properties_;
   fetch = function(el) { return el.Name; };

} else {  // Show property values
   var where = opts.Exists('WHERE') ? " where "+opts.Item('WHERE') : "";
   collection = wmi.ExecQuery( "Select * from " + clas + where );

   if ( (new Enumerator(collection)).atEnd() ) {  // No class found: check the alias
      var alias = GetObject("WinMgmts:\root\cli");
      collection = alias.ExecQuery("Select Target from Msft_CliAlias where FriendlyName='"+clas+"'");
      var e = new Enumerator(collection);
      if ( e.atEnd() ) {
         WScript.Stderr.WriteLine("Class or alias not exists: "+clas);
         WScript.Quit(1);
      }
      clas = e.item().Target.substr(14);
      collection = wmi.ExecQuery( "Select * from " + clas + where );
   }

   var prop = [];
   if ( args.Item(1) == "*" ) {  // Show all properties of this class; ignore rest, if any
      prop = enumerate( wmi.Get(clas).Properties_, function(el) { return el.Name; } );
   } else {  // Show given properties
      for ( var i = 1; i < args.length; i++ ) { prop.push(args.Item(i)); }
   }

   fetch = function(el) {
              var r = [];
              for ( var i = 0; i < prop.length; i++ ) {
                 var n = prop[i];
                 r.push(n + "=" + el[n]);
              }
              return r.join('\n');
           }
   ;

}

WScript.StdOut.WriteLine(enumerate(collection,fetch).join('\n'));

试试这个:

wmiClass memorychip manufacturer capacity

如果这个命令只显示一个结果,那么没有一个标准的方法来获取你的 4 个内存芯片的数据...

如果出现4个名字,那么就这样做:

set "i=0"
for /F "tokens=2 delims==" %%a in ('wmiClass memorychip manufacturer') do (
   set /A i+=1
   echo !i!# Memory Name : %%a
)

也许这个'more compact'单行命令更适合你:

@For /F "Skip=1 Delims=" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe MemoryChip Get BankLabel^, Manufacturer 2^>NUL') Do @For /F "Tokens=2,*" %%H In ("%%G") Do @Echo %%H# Memory Name : %%I

除非你没有 set 变量,否则你可能不会比这更紧凑:

@echo off & set cnt=0
setlocal enabledelayedexpansion
for /f "skip=1 delims=" %%i in ('wmic memorychip get capacity^,manufacturer') do for /f "tokens=1,*" %%a in ("%%i") do (
    set /a cnt+=1
    set "cap!cnt!=%%a"
    set "man!cnt!=%%b"
)
for /L %%r in (1,1,%cnt%) do echo(# %%r Manufacturer: !man%%r:  =!   Capacity: !cap%%r: =!

但是如果你不设置变量而只是使用元变量,它会更紧凑:

@echo off
for /f "skip=1 delims=" %%i in ('wmic memorychip get capacity^,manufacturer') do for /f "tokens=1,*" %%a in ("%%i") do echo Manufacturer: %%b Capacity %%a