在批处理文件中捕获PowerShell命令的输出';s/f循环
此PowerShell代码从此字符串中为在批处理文件中捕获PowerShell命令的输出';s/f循环,powershell,batch-file,for-loop,cmd,syntax,Powershell,Batch File,For Loop,Cmd,Syntax,此PowerShell代码从此字符串中为var5选择正确的值。它“发出警报”的预期结果 但是,在cmd shell脚本中使用相同的powershell代码会产生不同的结果。为什么呢?cmd shell是否需要转义某些内容 C:>type mat002-annex.bat @ECHO OFF SET "S=Status 58 var5=Alert Raised on: March" ECHO S is set to %S FOR /F %%a IN ('powershell -NoLog
var5
选择正确的值。它“发出警报”的预期结果
但是,在cmd shell脚本中使用相同的powershell代码会产生不同的结果。为什么呢?cmd shell是否需要转义某些内容
C:>type mat002-annex.bat
@ECHO OFF
SET "S=Status 58 var5=Alert Raised on: March"
ECHO S is set to %S
FOR /F %%a IN ('powershell -NoLogo -NoProfile -Command ^
" '%S%' | Where-Object { $_ -match '.*var5=(.*)\s+\w+:' } | ForEach-Object { $Matches[1] } "') DO (ECHO Result is "%%a")
C:>mat002-annex.bat
S is set to S
Result is "Alert"
批处理文件中不需要
for
循环
@ECHO OFF
SET "S=Status 58 var5=Alert Raised on: March"
powershell -NoLogo -NoProfile -Command " '%S%' | Where-Object { $_ -match '.*var5=(.*)\s+\w+:' } | ForEach-Object { $Matches[1] } "
上面给出了预期的结果。正如他经常做的那样,在评论中提供了关键的指针:
cmd.exe
的for/f
循环默认情况下会将其输入行按空格分隔成标记,以便for/f%%a in(…)do
只将第一个这样的标记放在变量%%a
中
可以使用选项字符串修改此默认行为:用于(…)do中的/f”“%%a
从
cmd.exe
提示符运行for/?
,说明其语法:
eol=c - specifies an end of line comment character
(just one)
skip=n - specifies the number of lines to skip at the
beginning of the file.
delims=xxx - specifies a delimiter set. This replaces the
default delimiter set of space and tab.
tokens=x,y,m-n - specifies which tokens from each line are to
be passed to the for body for each iteration.
This will cause additional variable names to
be allocated. The m-n form is a range,
specifying the mth through the nth tokens. If
the last character in the tokens= string is an
asterisk, then an additional variable is
allocated and receives the remaining text on
the line after the last token parsed.
usebackq - specifies that the new semantics are in force,
where a back quoted string is executed as a
command and a single quoted string is a
literal string command and allows the use of
double quotes to quote file names in
file-set.
如果希望在单个变量中捕获每个输入行,则有两个选项: 注意:下面的示例使用下面的PowerShell命令行,该命令行只输出一个包含多个前导、内部和尾随空格的字符串文本,
one-two
powershell -command " ' one two ' "
为了简化报价,下面使用了选项usebackq
,它允许将命令嵌入`…`
还要注意的是,将-NoProfile
添加到powershell.exe
的命令行是一种很好的做法,以防止不必要的、可能会改变行为的用户配置文件加载;为了简洁起见,我在下面省略了它
“delims=”
:按原样保留行
上述收益率:
Result is " one two "
Result is "one two "
请注意,前导空格和尾随空格也是如何保留的
重要:要将delims=
识别为停用基于分隔符(基于分隔符)的解析,必须将其置于选项字符串的最末尾。
“tokens=*”
:修剪前导空格
上述收益率:
Result is " one two "
Result is "one two "
请注意前导空格是如何修剪的
奇怪的是,修剪只应用于前导空格,而且似乎没有直接的方法来修剪尾随空格。
for/?
:默认情况下,/F
从每个文件的每一行传递第一个空格分隔的标记。@PetSerAl-是。完全正确我需要“代币=*”。为什么?省去批处理文件,直接使用PowerShell。PowerShell已经提供了10多年,并且自Windows 7以来一直是操作系统的内置部分。做开关;“这是值得投资的。”比尔·斯图尔特——我已经相信了。我不是做出这样决定的人。我会尽我所能。2012年前一个月发布的PowerShell 3是可行的。也许你的说法应该是它在五(5)年前是可用的。你是对的,这确实为stdout提供了正确的输出。我仍然需要做些什么才能把它变成一个变量。PetSerAl发现了它。鉴于(正如我们现在更清楚地知道的)意图是在变量中catpure PowerShell的输出,我可以建议您修改或删除您的答案吗?顺便说一句:虽然使用-NoProfile
是一种良好的做法,但将-NoLogo
与-Command
或-File
结合使用是不必要的。
Result is "one two "