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












0















Trying to find the difference. But when this powershell command is inside in the findstr, it fails. On its own, it returns the correct value. Also, without the loop, it returns the correct value.



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%
)


Can anyone figure out what I'm missing/did wrong?



Thanks in advance.










share|improve this question

























  • I have no idea what exactly may be included in %newvalue%, the code suggests from 00.0 to 99.9, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including a For loop with a call to PowerShell just to subtract an integer, i.e. 12, from %newvalue% is a little heavy handed.

    – Compo
    Jan 1 at 11:03













  • @Compo: first, checking if its dd.d. Next, doing a subtraction, -12.0 in this case. The powershell command line works on its own, but not inside this loop. I can't figure out why

    – Ricky
    Jan 1 at 11:07











  • @Ricky, I know what you're trying to do, I'm suggesting only that it may be a little over the top. What possible values are you expecting %newvalue% to hold?

    – Compo
    Jan 1 at 11:10











  • @Compo: I'm expecting a low number each time (d.d). I need the decimal point

    – Ricky
    Jan 1 at 11:11






  • 1





    Why could the entire thing not be done in either cmd.exe or powershell.exe. You said in your initial question that you didn't know how to retrieve the value in a batch file, but was shown how to do that. Set can be used to easily subtract 12.0 from %newvalue%. Because you have a known number of digits, 3, and a known position for the decimal point, that decimal point can be removed, the calculation done and the decimal point be replaced again. Calling PowerShell will certainly hit the execution time, so if it could be avoided in such a simple way, I'd recommend doing so.

    – Compo
    Jan 1 at 12:12


















0















Trying to find the difference. But when this powershell command is inside in the findstr, it fails. On its own, it returns the correct value. Also, without the loop, it returns the correct value.



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%
)


Can anyone figure out what I'm missing/did wrong?



Thanks in advance.










share|improve this question

























  • I have no idea what exactly may be included in %newvalue%, the code suggests from 00.0 to 99.9, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including a For loop with a call to PowerShell just to subtract an integer, i.e. 12, from %newvalue% is a little heavy handed.

    – Compo
    Jan 1 at 11:03













  • @Compo: first, checking if its dd.d. Next, doing a subtraction, -12.0 in this case. The powershell command line works on its own, but not inside this loop. I can't figure out why

    – Ricky
    Jan 1 at 11:07











  • @Ricky, I know what you're trying to do, I'm suggesting only that it may be a little over the top. What possible values are you expecting %newvalue% to hold?

    – Compo
    Jan 1 at 11:10











  • @Compo: I'm expecting a low number each time (d.d). I need the decimal point

    – Ricky
    Jan 1 at 11:11






  • 1





    Why could the entire thing not be done in either cmd.exe or powershell.exe. You said in your initial question that you didn't know how to retrieve the value in a batch file, but was shown how to do that. Set can be used to easily subtract 12.0 from %newvalue%. Because you have a known number of digits, 3, and a known position for the decimal point, that decimal point can be removed, the calculation done and the decimal point be replaced again. Calling PowerShell will certainly hit the execution time, so if it could be avoided in such a simple way, I'd recommend doing so.

    – Compo
    Jan 1 at 12:12
















0












0








0








Trying to find the difference. But when this powershell command is inside in the findstr, it fails. On its own, it returns the correct value. Also, without the loop, it returns the correct value.



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%
)


Can anyone figure out what I'm missing/did wrong?



Thanks in advance.










share|improve this question
















Trying to find the difference. But when this powershell command is inside in the findstr, it fails. On its own, it returns the correct value. Also, without the loop, it returns the correct value.



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%
)


Can anyone figure out what I'm missing/did wrong?



Thanks in advance.







powershell batch-file






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 1 at 11:20







Ricky

















asked Jan 1 at 10:08









RickyRicky

245




245













  • I have no idea what exactly may be included in %newvalue%, the code suggests from 00.0 to 99.9, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including a For loop with a call to PowerShell just to subtract an integer, i.e. 12, from %newvalue% is a little heavy handed.

    – Compo
    Jan 1 at 11:03













  • @Compo: first, checking if its dd.d. Next, doing a subtraction, -12.0 in this case. The powershell command line works on its own, but not inside this loop. I can't figure out why

    – Ricky
    Jan 1 at 11:07











  • @Ricky, I know what you're trying to do, I'm suggesting only that it may be a little over the top. What possible values are you expecting %newvalue% to hold?

    – Compo
    Jan 1 at 11:10











  • @Compo: I'm expecting a low number each time (d.d). I need the decimal point

    – Ricky
    Jan 1 at 11:11






  • 1





    Why could the entire thing not be done in either cmd.exe or powershell.exe. You said in your initial question that you didn't know how to retrieve the value in a batch file, but was shown how to do that. Set can be used to easily subtract 12.0 from %newvalue%. Because you have a known number of digits, 3, and a known position for the decimal point, that decimal point can be removed, the calculation done and the decimal point be replaced again. Calling PowerShell will certainly hit the execution time, so if it could be avoided in such a simple way, I'd recommend doing so.

    – Compo
    Jan 1 at 12:12





















  • I have no idea what exactly may be included in %newvalue%, the code suggests from 00.0 to 99.9, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including a For loop with a call to PowerShell just to subtract an integer, i.e. 12, from %newvalue% is a little heavy handed.

    – Compo
    Jan 1 at 11:03













  • @Compo: first, checking if its dd.d. Next, doing a subtraction, -12.0 in this case. The powershell command line works on its own, but not inside this loop. I can't figure out why

    – Ricky
    Jan 1 at 11:07











  • @Ricky, I know what you're trying to do, I'm suggesting only that it may be a little over the top. What possible values are you expecting %newvalue% to hold?

    – Compo
    Jan 1 at 11:10











  • @Compo: I'm expecting a low number each time (d.d). I need the decimal point

    – Ricky
    Jan 1 at 11:11






  • 1





    Why could the entire thing not be done in either cmd.exe or powershell.exe. You said in your initial question that you didn't know how to retrieve the value in a batch file, but was shown how to do that. Set can be used to easily subtract 12.0 from %newvalue%. Because you have a known number of digits, 3, and a known position for the decimal point, that decimal point can be removed, the calculation done and the decimal point be replaced again. Calling PowerShell will certainly hit the execution time, so if it could be avoided in such a simple way, I'd recommend doing so.

    – Compo
    Jan 1 at 12:12



















I have no idea what exactly may be included in %newvalue%, the code suggests from 00.0 to 99.9, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including a For loop with a call to PowerShell just to subtract an integer, i.e. 12, from %newvalue% is a little heavy handed.

– Compo
Jan 1 at 11:03







I have no idea what exactly may be included in %newvalue%, the code suggests from 00.0 to 99.9, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including a For loop with a call to PowerShell just to subtract an integer, i.e. 12, from %newvalue% is a little heavy handed.

– Compo
Jan 1 at 11:03















@Compo: first, checking if its dd.d. Next, doing a subtraction, -12.0 in this case. The powershell command line works on its own, but not inside this loop. I can't figure out why

– Ricky
Jan 1 at 11:07





@Compo: first, checking if its dd.d. Next, doing a subtraction, -12.0 in this case. The powershell command line works on its own, but not inside this loop. I can't figure out why

– Ricky
Jan 1 at 11:07













@Ricky, I know what you're trying to do, I'm suggesting only that it may be a little over the top. What possible values are you expecting %newvalue% to hold?

– Compo
Jan 1 at 11:10





@Ricky, I know what you're trying to do, I'm suggesting only that it may be a little over the top. What possible values are you expecting %newvalue% to hold?

– Compo
Jan 1 at 11:10













@Compo: I'm expecting a low number each time (d.d). I need the decimal point

– Ricky
Jan 1 at 11:11





@Compo: I'm expecting a low number each time (d.d). I need the decimal point

– Ricky
Jan 1 at 11:11




1




1





Why could the entire thing not be done in either cmd.exe or powershell.exe. You said in your initial question that you didn't know how to retrieve the value in a batch file, but was shown how to do that. Set can be used to easily subtract 12.0 from %newvalue%. Because you have a known number of digits, 3, and a known position for the decimal point, that decimal point can be removed, the calculation done and the decimal point be replaced again. Calling PowerShell will certainly hit the execution time, so if it could be avoided in such a simple way, I'd recommend doing so.

– Compo
Jan 1 at 12:12







Why could the entire thing not be done in either cmd.exe or powershell.exe. You said in your initial question that you didn't know how to retrieve the value in a batch file, but was shown how to do that. Set can be used to easily subtract 12.0 from %newvalue%. Because you have a known number of digits, 3, and a known position for the decimal point, that decimal point can be removed, the calculation done and the decimal point be replaced again. Calling PowerShell will certainly hit the execution time, so if it could be avoided in such a simple way, I'd recommend doing so.

– Compo
Jan 1 at 12:12














2 Answers
2






active

oldest

votes


















2














I recommend reading How does the Windows Command Interpreter (CMD.EXE) parse scripts?



Windows command processor replaces all environment variable references using syntax %variable% inside a command block starting with ( and ending with matching ) already on parsing the command line using this command block. This means the command line echo %difference% inside ELSE branch command block of the IF command is modified by cmd.exe before command IF is executed at all. %difference% is replaced by current value of environment variable difference or an empty string in case of environment variable difference is not defined somewhere above the IF condition. In latter case echo  is the command line remaining after parsing the command block and therefore shows status of command echoing instead of the string value assigned to environment variable difference in the command line above. The solution with already enabled delayed environment variable expansion is using echo !difference! in ELSE command block.



A solution for this floating point subtraction without usage of PowerShell can be seen below:



@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%System32findstr.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


After validating that the string assigned to environment variable NewValue indeed consists of two digits, a point and one more digit as requested and expected and described at How can I do a negative regex match in batch?, the floating point number string is split up on . into pre-comma and post-comma number strings.



The pre-comma number is subtracted by 12 using an arithmetic expression. But it must be taken into account that an integer number with a leading 0 is interpreted by cmd.exe on evaluation of the arithmetic expression as octal number. That is no problem for 00 to 07. But 08 and 09 would be invalid octal numbers and so Windows command processor would use value 0 resulting in a wrong subtraction result if simply set /A Difference=PreComma - 12 would have been used in batch file. The workaround is concatenating the string 1 with the pre-comma string to a number string in range 100 to 199 and subtract 112 to get the correct result.



The post-comma value does not need to be modified and so the Difference value is determined finally with concatenating the result of the arithmetic expression with the unmodified post-comma number string.



It is possible to get the Difference value also always with two digits by inserting following additional command lines above 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%"
)


This solution avoids also the problem that floating point result of PowerShell is formatted according to region and language settings. For example in Germany and Austria the decimal symbol is , and not . which means the subtraction result output by PowerShell for 15.3 - 12.0 is 3,3 and not 3.3.



For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.




  • echo /?

  • endlocal /?

  • findstr /?

  • for /?

  • goto /?

  • if /?

  • set /?

  • setlocal /?


See also single line with multiple commands using Windows batch file.






share|improve this answer































    0














    This is not technically an answer, as you've already received and accepted one a perfectly good one.



    It is just to allow you to visualise a method of taking the string from your file, splitting it at the decimal point and subtracting 12, from a whole number greater or equal to 12, (see the accepted answer for whole numbers less than 12), all without 'loops' or 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


    Obviously in your script proper, you'd only need:



    @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





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53994592%2fhow-to-make-this-powershell-command-work-inside-a-loop-in-batch%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      I recommend reading How does the Windows Command Interpreter (CMD.EXE) parse scripts?



      Windows command processor replaces all environment variable references using syntax %variable% inside a command block starting with ( and ending with matching ) already on parsing the command line using this command block. This means the command line echo %difference% inside ELSE branch command block of the IF command is modified by cmd.exe before command IF is executed at all. %difference% is replaced by current value of environment variable difference or an empty string in case of environment variable difference is not defined somewhere above the IF condition. In latter case echo  is the command line remaining after parsing the command block and therefore shows status of command echoing instead of the string value assigned to environment variable difference in the command line above. The solution with already enabled delayed environment variable expansion is using echo !difference! in ELSE command block.



      A solution for this floating point subtraction without usage of PowerShell can be seen below:



      @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%System32findstr.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


      After validating that the string assigned to environment variable NewValue indeed consists of two digits, a point and one more digit as requested and expected and described at How can I do a negative regex match in batch?, the floating point number string is split up on . into pre-comma and post-comma number strings.



      The pre-comma number is subtracted by 12 using an arithmetic expression. But it must be taken into account that an integer number with a leading 0 is interpreted by cmd.exe on evaluation of the arithmetic expression as octal number. That is no problem for 00 to 07. But 08 and 09 would be invalid octal numbers and so Windows command processor would use value 0 resulting in a wrong subtraction result if simply set /A Difference=PreComma - 12 would have been used in batch file. The workaround is concatenating the string 1 with the pre-comma string to a number string in range 100 to 199 and subtract 112 to get the correct result.



      The post-comma value does not need to be modified and so the Difference value is determined finally with concatenating the result of the arithmetic expression with the unmodified post-comma number string.



      It is possible to get the Difference value also always with two digits by inserting following additional command lines above 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%"
      )


      This solution avoids also the problem that floating point result of PowerShell is formatted according to region and language settings. For example in Germany and Austria the decimal symbol is , and not . which means the subtraction result output by PowerShell for 15.3 - 12.0 is 3,3 and not 3.3.



      For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.




      • echo /?

      • endlocal /?

      • findstr /?

      • for /?

      • goto /?

      • if /?

      • set /?

      • setlocal /?


      See also single line with multiple commands using Windows batch file.






      share|improve this answer




























        2














        I recommend reading How does the Windows Command Interpreter (CMD.EXE) parse scripts?



        Windows command processor replaces all environment variable references using syntax %variable% inside a command block starting with ( and ending with matching ) already on parsing the command line using this command block. This means the command line echo %difference% inside ELSE branch command block of the IF command is modified by cmd.exe before command IF is executed at all. %difference% is replaced by current value of environment variable difference or an empty string in case of environment variable difference is not defined somewhere above the IF condition. In latter case echo  is the command line remaining after parsing the command block and therefore shows status of command echoing instead of the string value assigned to environment variable difference in the command line above. The solution with already enabled delayed environment variable expansion is using echo !difference! in ELSE command block.



        A solution for this floating point subtraction without usage of PowerShell can be seen below:



        @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%System32findstr.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


        After validating that the string assigned to environment variable NewValue indeed consists of two digits, a point and one more digit as requested and expected and described at How can I do a negative regex match in batch?, the floating point number string is split up on . into pre-comma and post-comma number strings.



        The pre-comma number is subtracted by 12 using an arithmetic expression. But it must be taken into account that an integer number with a leading 0 is interpreted by cmd.exe on evaluation of the arithmetic expression as octal number. That is no problem for 00 to 07. But 08 and 09 would be invalid octal numbers and so Windows command processor would use value 0 resulting in a wrong subtraction result if simply set /A Difference=PreComma - 12 would have been used in batch file. The workaround is concatenating the string 1 with the pre-comma string to a number string in range 100 to 199 and subtract 112 to get the correct result.



        The post-comma value does not need to be modified and so the Difference value is determined finally with concatenating the result of the arithmetic expression with the unmodified post-comma number string.



        It is possible to get the Difference value also always with two digits by inserting following additional command lines above 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%"
        )


        This solution avoids also the problem that floating point result of PowerShell is formatted according to region and language settings. For example in Germany and Austria the decimal symbol is , and not . which means the subtraction result output by PowerShell for 15.3 - 12.0 is 3,3 and not 3.3.



        For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.




        • echo /?

        • endlocal /?

        • findstr /?

        • for /?

        • goto /?

        • if /?

        • set /?

        • setlocal /?


        See also single line with multiple commands using Windows batch file.






        share|improve this answer


























          2












          2








          2







          I recommend reading How does the Windows Command Interpreter (CMD.EXE) parse scripts?



          Windows command processor replaces all environment variable references using syntax %variable% inside a command block starting with ( and ending with matching ) already on parsing the command line using this command block. This means the command line echo %difference% inside ELSE branch command block of the IF command is modified by cmd.exe before command IF is executed at all. %difference% is replaced by current value of environment variable difference or an empty string in case of environment variable difference is not defined somewhere above the IF condition. In latter case echo  is the command line remaining after parsing the command block and therefore shows status of command echoing instead of the string value assigned to environment variable difference in the command line above. The solution with already enabled delayed environment variable expansion is using echo !difference! in ELSE command block.



          A solution for this floating point subtraction without usage of PowerShell can be seen below:



          @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%System32findstr.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


          After validating that the string assigned to environment variable NewValue indeed consists of two digits, a point and one more digit as requested and expected and described at How can I do a negative regex match in batch?, the floating point number string is split up on . into pre-comma and post-comma number strings.



          The pre-comma number is subtracted by 12 using an arithmetic expression. But it must be taken into account that an integer number with a leading 0 is interpreted by cmd.exe on evaluation of the arithmetic expression as octal number. That is no problem for 00 to 07. But 08 and 09 would be invalid octal numbers and so Windows command processor would use value 0 resulting in a wrong subtraction result if simply set /A Difference=PreComma - 12 would have been used in batch file. The workaround is concatenating the string 1 with the pre-comma string to a number string in range 100 to 199 and subtract 112 to get the correct result.



          The post-comma value does not need to be modified and so the Difference value is determined finally with concatenating the result of the arithmetic expression with the unmodified post-comma number string.



          It is possible to get the Difference value also always with two digits by inserting following additional command lines above 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%"
          )


          This solution avoids also the problem that floating point result of PowerShell is formatted according to region and language settings. For example in Germany and Austria the decimal symbol is , and not . which means the subtraction result output by PowerShell for 15.3 - 12.0 is 3,3 and not 3.3.



          For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.




          • echo /?

          • endlocal /?

          • findstr /?

          • for /?

          • goto /?

          • if /?

          • set /?

          • setlocal /?


          See also single line with multiple commands using Windows batch file.






          share|improve this answer













          I recommend reading How does the Windows Command Interpreter (CMD.EXE) parse scripts?



          Windows command processor replaces all environment variable references using syntax %variable% inside a command block starting with ( and ending with matching ) already on parsing the command line using this command block. This means the command line echo %difference% inside ELSE branch command block of the IF command is modified by cmd.exe before command IF is executed at all. %difference% is replaced by current value of environment variable difference or an empty string in case of environment variable difference is not defined somewhere above the IF condition. In latter case echo  is the command line remaining after parsing the command block and therefore shows status of command echoing instead of the string value assigned to environment variable difference in the command line above. The solution with already enabled delayed environment variable expansion is using echo !difference! in ELSE command block.



          A solution for this floating point subtraction without usage of PowerShell can be seen below:



          @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%System32findstr.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


          After validating that the string assigned to environment variable NewValue indeed consists of two digits, a point and one more digit as requested and expected and described at How can I do a negative regex match in batch?, the floating point number string is split up on . into pre-comma and post-comma number strings.



          The pre-comma number is subtracted by 12 using an arithmetic expression. But it must be taken into account that an integer number with a leading 0 is interpreted by cmd.exe on evaluation of the arithmetic expression as octal number. That is no problem for 00 to 07. But 08 and 09 would be invalid octal numbers and so Windows command processor would use value 0 resulting in a wrong subtraction result if simply set /A Difference=PreComma - 12 would have been used in batch file. The workaround is concatenating the string 1 with the pre-comma string to a number string in range 100 to 199 and subtract 112 to get the correct result.



          The post-comma value does not need to be modified and so the Difference value is determined finally with concatenating the result of the arithmetic expression with the unmodified post-comma number string.



          It is possible to get the Difference value also always with two digits by inserting following additional command lines above 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%"
          )


          This solution avoids also the problem that floating point result of PowerShell is formatted according to region and language settings. For example in Germany and Austria the decimal symbol is , and not . which means the subtraction result output by PowerShell for 15.3 - 12.0 is 3,3 and not 3.3.



          For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.




          • echo /?

          • endlocal /?

          • findstr /?

          • for /?

          • goto /?

          • if /?

          • set /?

          • setlocal /?


          See also single line with multiple commands using Windows batch file.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 1 at 12:20









          MofiMofi

          28.7k83778




          28.7k83778

























              0














              This is not technically an answer, as you've already received and accepted one a perfectly good one.



              It is just to allow you to visualise a method of taking the string from your file, splitting it at the decimal point and subtracting 12, from a whole number greater or equal to 12, (see the accepted answer for whole numbers less than 12), all without 'loops' or 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


              Obviously in your script proper, you'd only need:



              @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





              share|improve this answer




























                0














                This is not technically an answer, as you've already received and accepted one a perfectly good one.



                It is just to allow you to visualise a method of taking the string from your file, splitting it at the decimal point and subtracting 12, from a whole number greater or equal to 12, (see the accepted answer for whole numbers less than 12), all without 'loops' or 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


                Obviously in your script proper, you'd only need:



                @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





                share|improve this answer


























                  0












                  0








                  0







                  This is not technically an answer, as you've already received and accepted one a perfectly good one.



                  It is just to allow you to visualise a method of taking the string from your file, splitting it at the decimal point and subtracting 12, from a whole number greater or equal to 12, (see the accepted answer for whole numbers less than 12), all without 'loops' or 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


                  Obviously in your script proper, you'd only need:



                  @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





                  share|improve this answer













                  This is not technically an answer, as you've already received and accepted one a perfectly good one.



                  It is just to allow you to visualise a method of taking the string from your file, splitting it at the decimal point and subtracting 12, from a whole number greater or equal to 12, (see the accepted answer for whole numbers less than 12), all without 'loops' or 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


                  Obviously in your script proper, you'd only need:



                  @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






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 1 at 15:32









                  CompoCompo

                  16.5k3927




                  16.5k3927






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53994592%2fhow-to-make-this-powershell-command-work-inside-a-loop-in-batch%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                      ts Property 'filter' does not exist on type '{}'

                      mat-slide-toggle shouldn't change it's state when I click cancel in confirmation window