如何将getmac输出到批处理文件中的变量中并保留格式

时间:2017-07-26 16:50:07

标签: batch-file

我在这里找到的其他问题,我认为这样可行

SET LF=^


SET output=
SET getmac_cmd=getmac /v /fo list
FOR /F "USEBACKQ tokens=*" %%F in (`!getmac_cmd!`) DO (
    set output=!output!!LF!%%F
)
ECHO !output!

该命令的输出直接看起来像

Connection Name:  Local Area Connection
Network Adapter:  Intel Something
Physical Address: 00-00-00-00-00-00
Transport Name:   Media disconnected

Connection Name:  Bluetooth Network Connection
Network Adapter:  Bluetooth Something
Physical Address: 00-00-00-00-00-00
Transport Name:   Media disconnected

但是当通过批处理脚本运行时,我得到了

Connection Name:  Local Area Connection
Network Adapter:  Intel Something
Physical Address: 00-00-00-00-00-00
Transport Name:   Media disconnected
Connection Name:  Bluetooth Network Connection
Network Adapter:  Bluetooth Something
Physical Address: 00-00-00-00-00-00
Transport Name:   Media disconnected

有什么线索可以改变它以保持部分之间的实际空白线?

2 个答案:

答案 0 :(得分:2)

输出中缺少空行,因为for /F忽略空行。用户Mofi已在his answer中演示了如何使用findstr /N来解决此问题:

@echo off
setlocal EnableDelayedExpansion
(set LF=^
%= empty line =%
)
set "output="
for /F "tokens=1* delims=:" %%E in ('getmac /V /FO LIST ^| findstr /N /R "^"') do (
    set "output=!output!!LF!%%F"
)
echo/!output!
endlocal

但是,如果出现感叹号,则会失败,因为%%F在启用delayed expansion时会展开,这会消耗!。此外,前导冒号(尽管在getmac的输出中非常不可能)被删除,因为for /F将后续分隔符作为一个进行处理。

要解决这些问题,可以使用以下代码(请参阅解释性说明):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

(set LF=^
%= empty line =%
)

set "output="
for /F "delims=" %%E in ('getmac /V /FO LIST ^| findstr /N /R "^"') do (
    rem // Expand `for` variable `%%F` while delayed expansion is disabled:
    set "line=%%F"
    setlocal EnableDelayedExpansion
    rem /* Remove the leading line number and the first colon by sub-string replacement
    rem    (like `!line:*:=!`, see below) so every other leading colons are maintained;
    rem    since delayed expansion is toggled within the `for /F` loop, variable `output`
    rem    would not survive the `endlocal` barrier, so let another `for /F` loop carry
    rem    the whole assignment string, including the variable name, beyond `endlocal`;
    rem    that way, we do not have to care about empty strings or the default `eol`: */
    for /F "delims=" %%A in ("output=!output!!LF!!line:*:=!") do (
        endlocal
        rem // Again the `for` variable is expanded while delayed expansion is disabled:
        set "%%A"
    )
)

setlocal EnableDelayedExpansion
echo/!output!
endlocal

endlocal
exit /B

答案 1 :(得分:1)

在命令提示符窗口for /?中运行的多个页面上的帮助输出说明命令 FOR 忽略空行。

解决方案是使用带有选项/N的命令 FINDSTR 来输出每个找到的行之前的行号,它只是查找包含空行的所有行,并从此输出中删除行号。 / p>

getmac /v /fo list | findstr /R /N "^"的输出是:

1:Connection Name:  Local Area Connection
2:Network Adapter:  Intel Something
3:Physical Address: 00-00-00-00-00-00
4:Transport Name:   Media disconnected
5:
6:Connection Name:  Bluetooth Network Connection
7:Network Adapter:  Bluetooth Something
8:Physical Address: 00-00-00-00-00-00
9:Transport Name:   Media disconnected

要处理此输出并将其分配给环境变量output而没有行号的批处理文件是:

@echo off
setlocal EnableDelayedExpansion
set LF=^


set output=
for /F "tokens=1* delims=:" %%A in ('%SystemRoot%\System32\getmac.exe /v /fo list 2^>^&1 ^| %SystemRoot%\System32\findstr.exe /N /R "^"') DO set "output=!output!!LF!%%B"
echo !output!
endlocal

代码还通过使用 STDOUT 复制句柄来捕获写入 STDERR GETMAC 的错误输出,该句柄通过管道传输到 STDIN FINDSTR

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • getmac /?
  • set /?
  • setlocal /?

另请阅读Microsoft有关Using Command Redirection Operators的文章,了解2>&1|的解释。

运算符>&|必须使用符号字符^进行转义,才能在解析 FOR 命令行由Windows命令解释程序。

稍后由 FOR 在后台命令行的单独命令进程中执行:

C:\Windows\System32\getmac.exe /v /fo list 2>&1 | C:\Windows\System32\findstr.exe /N /R "^"