如何从命令 bcdedit /enumfirmware 的输出中获取不带尾随空格的固件描述?

问题描述 投票:0回答:1

执行

bcdedit /enum firmware | findstr "description"
会产生输出:

description             ATA HDD: ADATA SU650                             
description             LinuxMint
description             DisablePROCHOT UEFI
description             rEFInd Boot Manager

我使用

for
循环来处理输出:

@echo off
setlocal EnableDelayedExpansion
set "fwdes=bcdedit /enum firmware ^| findstr "description""
for /f "usebackq Tokens=1*" %%a in (`%fwdes%`) do echo [%%b]
pause

输出为:

[ATA HDD: ADATA SU650                             ]
[LinuxMint]
[DisablePROCHOT UEFI]
[rEFInd Boot Manager]

如何删除输出中 ATA HDD: ADATA SU650 之后的额外

尾随空格
,使其变成像其他行一样的
[ATA HDD: ADATA SU650]

我首先认为

ATA HDD: ADATA SU650
之后的空格是水平制表符,但事实证明,在将输出重定向到文本文件并使用十六进制编辑器查看文本文件后,它们是空格,在字符串之后显示带有十六进制
20
的字节硬盘。

使用此代码修复:

@echo off
setlocal EnableDelayedExpansion
set Sys32=%SystemRoot%\System32
set "fwdes=%Sys32%\bcdedit.exe /enum firmware^| %Sys32%\findstr.exe "description""
for /f "usebackq Tokens=1*" %%a in (`%fwdes%`) do (
    echo %%b | %Sys32%\findstr.exe /c:"SU650" >nul && (
    for /f "Tokens=1-4" %%s in ('echo %%b') do echo [%%s %%t %%u %%v]) || (echo [%%b])
)
pause

输出为:

[ATA HDD: ADATA SU650]
[LinuxMint]
[DisablePROCHOT UEFI]
[rEFInd Boot Manager]

也许有一种更快、更简单的方法。

for-loop batch-file cmd
1个回答
0
投票

获取输出不带尾随空格的固件描述的更好解决方案是:

@echo off & setlocal EnableExtensions DisableDelayedExpansion
(for /F "tokens=1*" %%I in ('%SystemRoot%\System32\bcdedit.exe /enum FIRMWARE ^| %SystemRoot%\System32\findstr.exe /B /L "description"') do set "Description=%%J" & call :Output) & pause & exit /B
:Output
if "%Description:~-1%" == " " (set "Description=%Description:~0,-1%" & goto Output) else echo [%Description%]& goto :EOF

批处理文件必须以管理员身份运行,否则不会输出任何内容,因为

bcdedit.exe
需要本地管理员的提升权限才能打开启动配置数据存储。

第一个命令行完整定义了所需的执行环境:

  1. 命令回显模式已关闭。
  2. 已根据此批处理文件的需要启用命令扩展。
  3. 延迟变量扩展因不需要而被禁用,并且需要进行处理,还可以纠正固件描述,其中包含一个或多个
    !

第二个命令行是单行批处理文件的主要代码,用于在批处理文件执行过程中最少的文件系统访问。

首先在后台执行的是

for /F
:

%ComSpec% /c %SystemRoot%\System32\bcdedit.exe /enum FIRMWARE | %SystemRoot%\System32\findstr.exe /B /L "description"

重定向运算符

|
必须在
FOR /F
命令行中用 ^ 进行转义,以便通过
cmd.exe
处理批处理文件进行字面解释。在后台启动的命令进程仅传递竖线字符,并将其解释为重定向运算符。

bcdedit.exe
的输出被重定向到
findstr.exe
,它会过滤掉所有不以字符串
description
开头(区分大小写)的行。

bcdedit.exe
的过滤输出是通过处理批处理文件的
cmd.exe
捕获的,并在启动的cmd.exe在执行两个可执行文件后自行关闭后由
FOR
逐行处理。

每个捕获的行都分为两个子字符串。第一个是

description
,它被分配给指定的循环变量
I
。根据 ASCII 表,将
description
之后的空格后的字符串及其所有空格(包括尾随空格)分配给下一个循环变量
J

在调用名为

Description
的子例程之前,将此字符串分配给环境变量
Output
,该子例程进一步处理描述并最终输出描述。此代码预计固件描述不包含一个或多个双引号。

子例程将环境变量

Description
的当前字符串值的最后一个字符与空格进行比较。如果该条件为真,则重新定义环境变量
Description
,不带尾随空格,并使用命令 GOTO 而不是不存在的下一个,通过在同一行上继续批处理文件处理来再次完成最后一个字符检查线。仅当当前描述的最后一个字符不是空格字符时,子程序 Output 中的 IF 条件的
ELSE
分支才会运行,并在方括号中输出修剪后的描述。然后使用
goto :EOF
退出子例程,并通过 FOR /F 继续处理下一个捕获的行。

一旦 FOR /F 循环处理完所有行,将执行命令 PAUSE 以暂停批处理文件处理,直到用户按下某个键,然后执行下一个

exit /B
以退出批处理文件的处理而不运行再次执行子程序中的命令
Output

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

  • bcdedit /?
  • bcdedit /enum /?
  • call /?
  • echo /?
  • exit /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?

另请参阅:

© www.soinside.com 2019 - 2024. All rights reserved.