从批处理文件的/f循环中的PowerShell命令捕获输出 [英] Capture output from a PowerShell command in a batch file's for /f loop
问题描述
此PowerShell代码从此字符串中为var5
选择正确的值.理想的结果是提高警惕".
This PowerShell code selects the correct value for var5
from this string. The desired result it "Alert Raised".
PS C:\src\t> $s = 'Status 58 var5=Alert Raised on: March'
PS C:\src\t> $s
Status 58 var5=Alert Raised on: March
PS C:\src\t> $s | Where-Object { $_ -match '.*var5=(.*)\s+\w+:' } | ForEach-Object { $Matches[1] }
Alert Raised
但是,在cmd shell脚本中使用相同的powershell代码会产生不同的结果.这是为什么?对于cmd shell,是否有一些需要转义的内容?
However, using the same powershell code in a cmd shell script produces a different result. Why is that? Is there something that needs to be escaped for the 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"
像他经常做的那样,
推荐答案
PetSerAl 提供了评论中的关键指针:
PetSerAl, as he often does, has provided the crucial pointer in a comment:
cmd.exe
的for /f
循环默认情况下将其输入行按空格分隔为令牌 ,因此for /f %%a in (...) do
仅将放在首位变量%%a
中的此类标记.
cmd.exe
's for /f
loop by default breaks its input lines into tokens by whitespace, so that for /f %%a in (...) do
only places the first such token in variable %%a
.
可以使用 options字符串 修改此默认行为:for /f "<options>" %%a in (...) do
.
从cmd.exe
提示符运行for /?
描述其语法:
This default behavior can be modified with an options string: for /f "<options>" %%a in (...) do
.
Running for /?
from a cmd.exe
prompt describes its syntax:
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
的字符串文字.
If you want each input line to be captured in a single variable, you have two options:
Note: The examples below use the following PowerShell command line, which simply outputs a string literal with multiple leading, inner, and trailing spaces, one two
.
powershell -command " ' one two ' "
为了简化报价,下面使用选项usebackq
,该选项允许将命令嵌入到`...`
中.
To make quoting easier, option usebackq
is used below, which allows embedding the command in `...`
.
还请注意,将-NoProfile
添加到powershell.exe
的命令行中是一种很好的做法,以防止不必要地加载用户个人资料,并可能会改变用户的个人资料;为了简洁起见,我在下面省略了它.
Also note that it's good practice to add -NoProfile
to powershell.exe
's command line to prevent unnecessary - and potentially behavior-changing - loading of a user's profile; I've omitted it below for brevity.
@echo off
for /f "usebackq delims=" %%a in (`powershell -command " ' one two ' "`) do echo Result is "%%a"
上面的产量:
Result is " one two "
请注意,前导空格和尾随空格也是如何保留的.
Note how the leading and trailing spaces were preserved too.
重要:要使 delims=
被识别为停用基于定界符(基于分隔符)的解析,必须放置在选项字符串的最末端.
Important: for delims=
to be recognized as deactivating delimiter-based (separator-based) parsing, it must be placed at the very end of the options string.
@echo off
for /f "usebackq tokens=*" %%a in (`powershell -command " ' one two ' "`) do echo Result is "%%a"
上面的结果:
Result is "one two "
请注意前导空格是如何修饰的.
奇怪的是,修整仅应用于前导空白,并且似乎也没有直接的方法来修整尾随空白.
It is curious that the trimming is only applied to leading whitespace, and there appears to be no direct way to trim trailing whitespace as well.
这篇关于从批处理文件的/f循环中的PowerShell命令捕获输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!