我在这里找到的其他问题,我认为这样可行
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
有什么线索可以改变它以保持部分之间的实际空白线?
答案 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 "^"