繁体   English   中英

如何使此powershell命令在循环内批量工作?

[英]How to make this powershell command work inside a loop in batch?

试图找到差异。 但是,当此powershell命令位于findstr中时,它将失败。 它自己返回正确的值。 同样,没有循环,它将返回正确的值。

echo:!newvalue!| findstr /R "^[0123456789][0123456789]\.[0123456789]$" >nul
  if errorlevel 1 (
    set newvalue=
  ) else (
    FOR /F "usebackq delims=" %%i IN (`powershell -nop -c "'{0:n1}' -f (%newvalue% - 12.0)"`) DO (SET difference=%%i)
    echo %difference%
  )

谁能弄清楚我的缺失/做错了什么?

提前致谢。

我建议阅读Windows命令解释器(CMD.EXE)如何解析脚本?

Windows命令处理器使用语法%variable%替换命令块内所有的环境变量引用,该命令块以使用此命令块解析命令行时已经(以match结束)开头。 这意味着,在完全执行命令IF之前, cmd.exeIF命令的ELSE分支命令块内的命令行echo %difference%修改。 %difference%将替换为环境变量difference的当前值,或者如果在IF条件以上的某个位置未定义环境变量difference ,则将使用空字符串。 在后一种情况下, echo是在解析命令块之后保留的命令行,因此显示了命令回显的状态,而不是上面命令行中分配给环境变量difference的字符串值。 具有已启用的延迟环境变量扩展的解决方案是使用echo !difference! ELSE命令块中。

在不使用PowerShell的情况下,此浮点减法的解决方案如下所示:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
if defined NewValue goto Validate

:UserPrompt
set /P "NewValue=Enter value between 00.0 and 99.9: "

:Validate
echo:!NewValue!| %SystemRoot%\System32\findstr.exe /R "^[0123456789][0123456789]\.[0123456789]$" >nul
if errorlevel 1 set "NewValue=" & goto UserPrompt

for /F "tokens=1,2 delims=." %%I in ("%NewValue%") do set "PreComma=%%I" & set "PostComma=%%J"
set /A Difference=1%PreComma% - 112
set "Difference=%Difference%.%PostComma%"
echo Difference is: %Difference%
endlocal

确认分配给环境变量NewValue的字符串确实由两位数字组成,一个点和一个数字再根据要求和预期并在如何进行负正则表达式匹配中进行了描述 ,则浮点数字符串在上分割. 分为逗号前和逗号后的数字字符串。

使用算术表达式将逗号前数减去12。 但是必须考虑到,在算术表达式的评估中, cmd.exe将前导0的整数解释为八进制数。 0007没问题。 但是0809将是无效的八进制数字,因此,如果简单地set /A Difference=PreComma - 12 ,则批处理文件中的Windows命令处理器将使用值0导致错误的减法结果。 解决方法是将字符串1与逗号前字符串连接到100199范围内的数字字符串,然后减去112以得到正确的结果。

逗号后的值不需要修改,因此最终通过将算术表达式的结果与未修改的逗号后的数字字符串连接起来来确定Difference

通过在echo Difference is: %Difference%上方插入以下附加命令行,也可以总是始终以两位数来获得Difference分值echo Difference is: %Difference%

if %Difference:~0,1% == - (
    if %Difference:~2,1% == . set "Difference=-0%Difference:~1%"
) else (
    if %Difference:~1,1% == . set "Difference=0%Difference%"
)

该解决方案还避免了PowerShell浮点结果根据区域和语言设置进行格式化的问题。 例如,在德国和奥地利, 小数点符号,而不是. 这意味着PowerShell为15.3 - 12.0输出的减法结果为3,3而不是3.3

为了了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

另请参阅使用Windows批处理文件的单行和多个命令

从技术上讲,这不是一个答案,因为您已经收到并接受了一个非常好的答案。

这只是为了让您可视化一种从文件中提取字符串,将其拆分为小数点并从大于或等于12的整数中减去12 (对于小于12整数,请参见接受的答案)。 ,都没有“循环”或PowerShell

@Echo Off

Rem Create a variable from the first line of your file
Set /P "newvalue="<"file.tmp"
Echo [%newvalue%]

Rem Exit if the string 'value' does not exist in '%newvalue%'
If "%newvalue%"=="%newvalue:*value=%" Exit /B

Rem ReSet the variable to everything after the string 'value'
Set "newvalue=%newvalue:*value=%"
Echo [%newvalue%]

Rem ReSet the variable to everything up to the first 'space' character
Set "newvalue=%newvalue: ="&:"%"
Echo [%newvalue%]

Rem ReSet the variable, removing the unneeded leading '=' character
Set "newvalue=%newvalue:~1%"
Echo [%newvalue%]

Rem Set a new variable to the whole number, i.e. everything up to the first '.' character
Set "whole=%newvalue:.="&:"%"
Echo [%whole%]

Rem Set a new variable to the decimal, i.e. everything after the '.' character
Set "decimal=%newvalue:*.=%"
Echo [%decimal%]

Rem Subtract 12 from the whole number
Set /A remainder=100+whole-112
Echo [%remainder%]

Rem ReJoin the variables to show the difference
Echo [%remainder%.%decimal%]

Pause

显然,在适当的脚本中,您只需要:

@Echo Off
Set /P "newvalue="<"file.tmp"
If "%newvalue%"=="%newvalue:*value=%" Exit /B
Set "newvalue=%newvalue:*value=%"
Set "newvalue=%newvalue: ="&:"%"
Set "newvalue=%newvalue:~1%"
Set "whole=%newvalue:.="&:"%"
Set "decimal=%newvalue:*.=%"
Set /A remainder=100+whole-112
Echo %remainder%.%decimal%
Pause

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM