I'm trying to extract the highest number from a list of integers saved to a file.
Example of the text file I read:
10
52
20
I can loop through the elements and find the correct result, but I'm having trouble saving it outside the loop. I don't have much experience with batch files, I just understand that it's a variable scope problem, but I don't understand how to fix it.
The batch in question is called from another batch, which contains the following commands:
@echo off
setlocal DisableDelayedExpansion
setlocal EnableExtensions
call script.bat
script.bat
set "max_value=0"
setlocal EnableDelayedExpansion
set "MaxNumber=0"
for /f "delims=" %%V in (%output_txt%) do (
if not "%%V"=="" (
for /F "tokens=* delims=0" %%N in ("%%V") do if %%N GTR !MaxNumber! set "MaxNumber=%%N"
)
)
echo Biggest number is: %MaxNumber%
set max_value=%MaxNumber%
endlocal
echo Biggest number is: %max_value%
Output obtained from the example:
Biggest number is: 145
Biggest number is: 0
I've seen several questions regarding the scope issue in similar situations, but I can't resolve or figure out where the error is?
CodePudding user response:
setlocal
makes a copy of the current environment and processing continues using that new environment. An endlocal
statement disposes of the new environment and restores the original (reaching physical end-of-file is an implicit endlocal
.) When the original environment is restored, any changes made to it are backed out as though they had never happened so any value that is required beyond the setlocal/endlocal
bracket needs to be preserved. You can write those values to a file and then read them back again after the endlocal
, or use a parsing trick.
Batch first parses the line to validate it, then executes the parsed version. If the endlocal
line is structured like this:
endlocal&set "var=%var%"
which may seem illogical, but the parser changes it to, and cmd
executes it as
endlocal&set "var=thecurrentcontentsofvar"
"moving" the variable across the "endlocal barrier
".
CodePudding user response:
You could, of course, get PowerShell to help you with this.
Here's an example line for your batch-file to get you on your way:
For /F %%G In ('powershell -NoP "(GC '%output_txt%' | Measure -Max).Maximum"') Do Echo Biggest number is: %%G
You could of course do it the less lazy way:
For /F %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content -Path '%output_txt%' | Measure-Object -Maximum).Maximum"') Do Echo Biggest number is: %%G