如何从Windows批处理文件中的PowerShell中正确设置变量?

时间:2018-12-30 11:28:11

标签: powershell batch-file

由于某些未知原因,我无法在Windows批处理文件中检索此变量。

PowerShell:

$datePattern = [Regex]::new('value=(\S+)')
$datePattern = [Regex]::new('(\d\d\.\d)')
$matches = $datePattern.Matches("/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /")
$matches.Value

效果很好。 但是,这在批处理文件上失败了。

for /f %%i in ("PowerShell -NoProfile -ExecutionPolicy Bypass -Command $datePattern = [Regex]::new(value=(\S+)); $datePattern = [Regex]::new((\d\d\.\d)); $matches = $datePattern.Matches(tmpFile); $matches.Value") do ( set newValue=%%i )

目标是使%newValue% value = 返回 12.2 。如果可以直接在批处理文件上完成操作,那就更好了。这些值因文件而异。

3 个答案:

答案 0 :(得分:0)

我不太确定您想从正则表达式中得到什么,但是在您的代码中,您将$datePattern设置为value=(\S+)后立即重新定义了它。

使用\S+似乎并不关心值的格式,只要它不是空格即可。 在正则表达式的第二个定义中,您确实希望该值正好是两位数字,然后是一个点,然后是另一个数字。

如果您要查找的是确切的数字格式,请这样做

$datePattern = [Regex]::new('value=(\d\d\.\d)')

使用

执行时
$m = $datePattern.Matches("/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /")

您将获得$m.Value,结果为value=12.2
$m.Groups[1].Value为您提供12.2

的结果

如果您要查找数字值但不知道确切格式,则最好将正则表达式更改为以下形式:'value=(\d+.\d+)'

答案 1 :(得分:0)

为文件tmpfile IS 提供了一个单行文件,且不超过最大cmd行长。

批次

:: Q:\Test\2018\12\30\SO_53977221_.cmd
@Echo off
set /P "string="<tmpfile
set "string=%string:*value=%"
set "newvalue=%string:~1,4%"
set newvalue

>  SO_53977221_.cmd
newvalue=12.2

这使用字符串替换(带有通配符)和子字符串来获得所要查询的值。

也可以使用批处理/ powershell组合解决方案,但是转义和引用比尝试花费更多的精力。

此PowerShell一个衬板将输出

PoSh> if((Get-Content .\tmpfile) -match 'value=(\d\d\.\d)'){$Matches[1]}
12.2

正确分批包装

:: Q:\Test\2018\12\30\SO_53977221.cmd
@Echo off
for /f "usebackq" %%A in (`
    powershell -NoP -C "if((Get-Content .\tmpfile) -match 'value=(\d\d\.\d)'){$Matches[1]}"
`) Do set "newvalue=%%A"
set newvalue

示例输出:

> .\SO_53977221.cmd
newvalue=12.2

答案 2 :(得分:0)

这与正确的quoting and escaping有关。阅读powershell -?(节录被截断):

-Command

Executes the specified commands (and any parameters) as though they were
typed at the Windows PowerShell command prompt, and then exits, unless
NoExit is specified. The value of Command can be "-", a string. or a
script block.
…
If the value of Command is a string, Command must be the last parameter
in the command , because any characters typed after the command are
interpreted as the command arguments.

To write a string that runs a Windows PowerShell command, use the format:
    "& {<command>}"
where the quotation marks indicate a string and the invoke operator (&)
causes the command to be executed.

我们的<command>包含双引号:

$datePattern = [Regex]::new('(\d\d\.\d)');$matches = $datePattern.Matches("/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /");$matches.Value

使用单引号代替,如下:

$datePattern = [Regex]::new('(\d\d\.\d)');$matches = $datePattern.Matches('/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /');$matches.Value

double 内部双引号两次

$datePattern.Matches(""""/ … / value=12.2 / … /"""")

完整的powershell调用如下所示:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {$datePattern = [Regex]::new('(\d\d\.\d)');$matches = $datePattern.Matches(""""/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /"""");$matches.Value}"

最后,应用FOR /F Loop command: against the results of another command

for /f "usebackq" %i in (`PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {$datePattern = [Regex]::new('(\d\d\.\d)');$matches = $datePattern.Matches(""""/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /"""");$matches.Value}"`) do ( set "newValue=%i" )

后一个命令在命令提示符下起作用。 Double the % sign in a batch script

for /f "usebackq" %%i in (`PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {$datePattern = [Regex]::new('(\d\d\.\d)');$matches = $datePattern.Matches(""""/ start=2010 / height=1 / value=12.2 / length=0.60 / users=264 / best=Adam /"""");$matches.Value}"`) do ( set "newValue=%%i" )