我试图从批处理文件中的for /f
循环中获取一个简单的值。
使用命令wmic path win32_localtime get dayofweek
为我提供输出:
C:\sendemail>wmic path win32_localtime get dayofweek
DayOfWeek
1
C:\sendemail>
因此,使用以下批处理脚本,我应该能够返回" 1"的结果:
set cmd=wmic path win32_localtime get dayofweek
for /f "tokens=1 skip=1" %%Z in ('%cmd%') do set _myday=%%Z
echo Var is %_myday%
但是我没有,它将变量设置至少两次,如下所示:
C:\sendemail>set cmd=wmic path win32_localtime get dayofweek
C:\sendemail>for /F "tokens=1 skip=1" %Z in ('wmic path win32_localtime get dayofweek') do set _myday=%Z
C:\sendemail>set _myday=1
:\sendemail>set _myday=
C:\sendemail>echo Var is
Var is
C:\sendemail>
起初,我想知道为什么,然后我意识到循环正在处理两个空行......它不应该是。根据这个:http://ss64.com/nt/for_cmd.html
Skip SKIP将从头开始跳过处理多行 文件。 SKIP包含空行,但在SKIP完成后, FOR / F忽略(不迭代)空行。
要么,它不能正常工作,要么这些线不是空白的,并且充满了某些东西......
无论如何,我如何得到一周中的一天结果,而忽略其余部分?
答案 0 :(得分:7)
关于行内容,是的,wmic
的输出在每行的末尾包含for
命令检测到的附加回车符。这就是非空行的原因。
您可以尝试使用
for /f "tokens=2 delims==" %%Z in ('
wmic path win32_localtime get dayofweek /value
') do for /f %%Y in ("%%Z") do set "_myday=%%Y"
代码要求wmic
以key=value
格式返回信息,并使用等号来标记输入记录。由于我们只请求第二个令牌,for
将仅处理返回至少两个令牌的行,具有键(第一个令牌),等号(分隔符)和值(第二个令牌)的行
但是,该行末尾的附加回车符也包含在变量的值中。
当变量与普通语法(%_myday%
)一起使用时,它不会被看到,但是如果延迟扩展(!_myday!
),则会回显附加回车符。
要从变量中删除此附加字符,已在发布的代码中使用了第二个for
命令。
答案 1 :(得分:2)
这种轻微的中间化将起作用:
@ECHO OFF
set cmd=wmic path win32_localtime get dayofweek
for /f "tokens=1 skip=1" %%Z in ('%cmd%') do (
set _myday=%%Z
GOTO BREAK
)
:BREAK
echo Var is %_myday%
PAUSE
读取所需的行后,只需跳出循环。
答案 2 :(得分:0)
以上是一个很好的方法,从一开始我就成功地应用了它。由于还需要捕获WMI变量并将其加载到环境变量中,因此我希望其中一些可以作为本机命令行。我偶然发现了这个...
for /F "skip=2 tokens=2 delims=," %%i IN ('wmic timezone get Bias /format:csv') do (echo var Bias=%%i; > %TZONEDB%mid.htm )
核心是使用CSV格式可以跳过工作(没有尾随空格),并且可以轻松解析输出。
ed g
答案 3 :(得分:0)
我最近在这里讨论了这个问题,而以前的答案对我有帮助,我想检索几个变量以进行后续测试。最初,我使用类似于以下示例的代码(只是在explorer.exe上不使用,并且具有不同的变量名。已故意选择以下变量名以匹配后面的代码中的变量名限制)。 / p>
setlocal
for /F "skip=2 tokens=2,3,4 delims=," %%a in ('
wmic /node:"MyFileServer-pc" process where Name^="explorer.exe"
get HandleCount^,
ParentProcessId^,
ThreadCount
/format:csv
') do (
set ProcHandleCount=%%a
set ProcParentProcessId=%%b
set ProcThreadCount=%%c
)
echo HandleCount %ProcHandleCount%, ParentProcessID %ProcParentProcessId%, ThreadCount %ProcThreadCount%
但是,我不喜欢这种解决方案,因为wmic总是以内部迭代它们的顺序返回结果,而不管它们呈现给wmic命令的顺序如何,因此命令wmic process where Name^="explorer.exe" get ThreadCount^,HandleCount^,ParentProcessId
仍然最后返回ThreadCount。这样一来,在获取多个参数值对时,先前的代码很容易出错,并且很难获得正确的排序。
因此,我改为使用以下代码,该代码可实现相同的结果,而无需关心wmic参数的顺序。无需担心订购也可以轻松添加其他参数。
setlocal
for /F "tokens=1,2delims==" %%a in ('
wmic /node:"MyFileServer-pc" process where Name^="explorer.exe"
get HandleCount^,
ParentProcessId^,
ThreadCount
/value
') do @set Proc%%a^=%%b
echo HandleCount %ProcHandleCount%, ParentProcessID %ProcParentProcessId%, ThreadCount %ProcThreadCount%
在上面的代码中,变量名由来自wmic的每个返回的 parameter = value 对的 parameter 提供,并带有固定前缀,自动匹配返回的参数和值对。请注意,使用前缀(在这种情况下为'Proc'),而没有返回至少一个字符前缀,则wmic空行会导致错误。如果需要不同的环境变量名称,则第一种解决方案可以自由命名,并允许使用较短的名称,但是在需要多个值时更容易出错。 不管花多少钱,下面的代码都避免了变量前缀并使错误静音。通常需要更多唯一的变量名。
(
for /F "tokens=1,2delims==" %%a in ('
wmic /node:"MyFileServer-pc" process where Name^="explorer.exe" get HandleCount^,ParentProcessId^,ThreadCount /value
') do @set %%a=%%b
) 2>nul
这些示例使用wmic参数/ node:“ MyFileServer-pc”获取远程进程信息,但对于更简单的wmic命令同样有效。
答案 4 :(得分:0)
我在处理 wmic 输出时总是使用这个批处理模板:
setlocal enableextensions enabledelayedexpansion
for /f "delims and such" %%a in ('wmic path win32_localtime get dayofweek 2^>nul ^<nul') do (
set VAR=%%a
CALL :RMCRLF VAR
if "!VAR!" NEQ "" (
rem If we get here, then it's a non-empty line
rem ... Do something ...
)
)
GOTO :EOF
:RMCRLF
:: All this does is clean stray carriage returns/line feeds off of a variable,
:: which wmic is notorious for injecting into its output.
set RMCRVAR=%1
IF NOT DEFINED RMCRVAR GOTO :EOF
CALL set %RMCRVAR%=%%%RMCRVAR%%%
GOTO :EOF
这里的关键是“功能”(如果您愿意的话):RMCRLF。它将从变量中去除讨厌的回车符,以便您可以检查字符串是否真正为空,然后决定跳过空行。