How to make this powershell command work inside a loop in batch?
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
|
show 2 more comments
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
I have no idea what exactly may be included in%newvalue%
, the code suggests from00.0
to99.9
, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including aFor
loop with a call toPowerShell
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 subtract12.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
|
show 2 more comments
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
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
powershell batch-file
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 from00.0
to99.9
, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including aFor
loop with a call toPowerShell
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 subtract12.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
|
show 2 more comments
I have no idea what exactly may be included in%newvalue%
, the code suggests from00.0
to99.9
, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including aFor
loop with a call toPowerShell
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 subtract12.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
|
show 2 more comments
2 Answers
2
active
oldest
votes
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.
add a comment |
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Jan 1 at 12:20
MofiMofi
28.7k83778
28.7k83778
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Jan 1 at 15:32
CompoCompo
16.5k3927
16.5k3927
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
I have no idea what exactly may be included in
%newvalue%
, the code suggests from00.0
to99.9
, but that code was only a suggestion from @Mofi in their unaccepted answer to your previous question. It may therefore be that including aFor
loop with a call toPowerShell
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 subtract12.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