从批处理文件的/f循环中的PowerShell命令捕获输出 [英] Capture output from a PowerShell command in a batch file's for /f loop

查看:258
本文介绍了从批处理文件的/f循环中的PowerShell命令捕获输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此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.exefor /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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆