SETLOCAL ENABLEDELAYEDEXPANSION
SET /A Counter = 0
SET /A Limit = 5
:File_Check
IF EXIST D:\Automation\OTOT_OBAL\Automation\myfilter.jar (
GOTO Trigger_Found
)
ELSE IF %Counter% LSS %Limit% (
timeout /t 5 /nobreak >null
SET /A Counter = Counter + 1
GOTO File_Check
)
GOTO (VERYEND)
ENDLOCAL
:Trigger_Found
echo ON
echo TRIGGER FOUND
Exit
:VERYEND
echo !Counter!
echo program has reached maximum wait time we are going to exit.
Exit
The else is redundant, but if used must be on the same physical line as the preceding )
The target of the final goto is the label (veryend) not the label veryend.
In the absence of current code:
IF EXIST D:\Automation\OTOT_OBAL\Automation\myfilter.jar (
GOTO Trigger_Found
) ELSE IF %Counter% LSS %Limit% (
timeout /t 5 /nobreak >null
SET /A Counter = Counter + 1
GOTO File_Check
)
GOTO VERYEND
should work
IF EXIST D:\Automation\OTOT_OBAL\Automation\myfilter.jar GOTO Trigger_Found
IF %Counter% LSS %Limit% (
timeout /t 5 /nobreak >null
SET /A Counter = Counter + 1
GOTO File_Check
)
GOTO VERYEND
would probably be better.
Related
I am attempting to figure out a way to do returning if then statements in the for command, here's the code so far:
We have a file called: File.cfg with multiple numbers (no more than 6 numbers):
1
3
4
6
2
5
Setting those numbers as variables:
setlocal enabledelayed expansion
setlocal
set /a count=1
for /F "usebackq delims=" %%a in ( File.cfg ) do (
set line!count!=%%a
set /a count+=1
)
Then attempting to do a returning if then operations:
set /a count=0
echo 1 > list.txt
:Loop
set /a count+=1
echo %count% > list.txt
FOR /F "usebackq delims= " %%a in (list.txt) do (
echo !line%%a!
if %%a==7 goto :eof
if !line%%a!==1 goto 1
if !line%%a!==2 goto 2
if !line%%a!==3 goto 3
if !line%%a!==4 goto 4
if !line%%a!==5 goto 5
if !line%%a!==6 goto 6
)
Example of the goto #'s
:1
code
code
code
goto loop
Though in the end, the batch program ends prematurely, mainly at count 1.
Final output results:
( echo !line1!
if 1 == 7 goto :eof
if !line1! == 1 goto 1
if !line1! == 2 goto 2
if !line1! == 3 goto 3
if !line1! == 4 goto 4
if !line1! == 5 goto 5
if !line1! == 6 goto 6
)
1
Not sure why you have the complicated code unless you are trying to do a proof of concept on something. In my experience the easiest way to achieve your desired outcome is to do this.
#echo off
for /F "usebackq delims=" %%a in ("File.cfg") do CALL :%%a
REM END OF MAIN Functions below
GOTO :EOF
:1
ECHO IN 1
GOTO :EOF
:2
ECHO IN 2
GOTO :EOF
REM Shortened for brevity
The code above will output
IN 1
IN 3
IN 4
IN 6
IN 2
IN 5
If you really want to use array variables then again the easiest solution is the following code.
#echo off
setlocal enabledelayedexpansion
set "count=0"
for /F "usebackq delims=" %%a in ("File.cfg") do (
set /a "count+=1"
set "line!count!=%%a"
)
FOR /L %%G IN (1,1,%count%) DO CALL :!line%%G!
REM END OF MAIN Functions below
GOTO :EOF
:1
ECHO IN 1
GOTO :EOF
:2
ECHO IN 2
GOTO :EOF
REM Shortened for brevity
The aforementioned code will also output
IN 1
IN 3
IN 4
IN 6
IN 2
IN 5
So, I am working on a batch TD game, and whenever i test it and play through Round 1, It crashes instantly. I have no idea what could cause this. I'll send the code, Thanks in advance! (healing and conceding doesnt work right now)
#echo off
goto gamediff
:gamediff
cls
echo GAME COLOUR
echo.
echo [1] Blue (Easy)
echo [2] Yellow (Normal)
echo [3] Red (Hard)
set /p col=
if %col% == 1 set /a cashamm= 500 & set /a damamm= 30 & goto gameload
if %col% == 2 set /a cashamm= 250 & set /a damamm= 50 & goto gameload
if %col% == 3 set /a cashamm= 250 & set /a damamm= 60 & goto gameload
goto gamediff
:gameload
set /a turn= 1
set /a basic= 0
set /a heavy= 0
set /a snip= 0
set /a total= 0
set /a cash= %cashamm%
set /a dam= %damamm%
set /a attack= 0
set /a heal= 3
set /a health= 500
ping 127.0.0.1 -n 2 > nul
if %col% == 1 color b0
if %col% == 2 color f0
if %col% == 3 color c0
goto game
:game
cls
set /a nonpro= %dam%
echo Round %turn%
echo Cash: %cash%
echo Opponent Damage: %dam%
echo Your Protection: %attack%
echo Helth: %health%
echo.
echo STATS
echo Basic Troops: %basic%
echo Heavy Troops: %heavy%
echo Sniping Troops: %snip%
echo TOTAL: %total%
echo.
echo.
echo [0] Concede
echo [1] Play Round
echo [2] Recruitment
echo [3] Heal (Heals left: %heal%)
set /p gamin=
if %gamin% == 0 goto lose
if %gamin% == 1 goto play
if %gamin% == 2 goto shop
if %gamin% == 3 goto healtime
goto game
:play
cls
echo YOU PROTECT!
ping 127.0.0.1 -n 2 > nul
echo %attack% PROTECTED
ping 127.0.0.1 -n 3 > nul
echo.
echo THEY ATTACK!
ping 127.0.0.1 -n 2 > nul
set /a nonpro-= %attack%
if %nonpro% LSS 1 set /a nonpro= 0
set /a health-= %nonpro%
echo -%nonpro% HEALTH!
pause
if %health% LSS 1 goto lose
if %round% GTR 50 goto win
set /a round+= 1
set /a dam+= %random% %% 20
set /a cash+= %random% %% 100
goto game
:shop
cls
echo Recruitment
echo.
echo [0] Leave
echo [1] Basic Troop (-50 Cash, +15 Protection)
echo [2] Heavy Troop (-100 Cash, +40 Protection)
echo [3] Sniping Troop (-70 Cash,+25 Protection)
set /p shope=
if %shope% == 0 goto game
if %shope% == 1 goto buy1
if %shope% == 2 goto buy2
if %shope% == 3 goto buy3
goto shop
:buy1
if cash LSS 50 goto game
set /a cash-= 50
set /a attack+= 15
goto game
:buy2
if cash LSS 100 goto game
set /a cash-= 100
set /a attack+= 40
goto game
:buy3
if cash LSS 70 goto game
set /a cash-= 70
set /a attack+= 25
goto game
Thanks to anyone who can help me!
If you need more information, please ask for it in the comments.
You can contact me through whatever this site has if you run into any more problems. I can also help you with any questions you have, quickly.
lose and win are non-existent labels. Use quotations when using if, and also with set unless you're declaring a variable as another. The /a switch is not necessary for set whenever arithmetic is not being performed.
Other proper things to do while writing in batch:
--In a goto statement ensure the label is preceded with a colon :.
--When prompting user input in the form of selection with under 9 options, use the choice command. It's more suitable.
--Your variable names should make sense.
--Batch is slow, inefficient, unreliable, elementary, featureless, and basic. Opt for a better coding language that's simple but much, much better, like VB.NET or Python. Batch is barely even a coding language.
The following code has most of the problems I mentioned fixed, except for the choice one because, in some cases, set could be a better option.
#echo off
goto gamediff
:gamediff
cls
echo GAME COLOUR
echo.
echo [1] Blue (Easy)
echo [2] Yellow (Normal)
echo [3] Red (Hard)
set /p "col=>"
if %col% == 1 set /a cashamm = 500 & set /a damamm = 30 & goto gameload
if %col% == 2 set /a cashamm = 250 & set /a damamm = 50 & goto gameload
if %col% == 3 set /a cashamm = 250 & set /a damamm = 60 & goto gameload
goto :gamediff
:gameload
set /a turn = 1
set /a basic = 0
set /a heavy = 0
set /a snip = 0
set /a total = 0
set /a cash = %cashamm%
set /a dam = %damamm%
set /a attack = 0
set /a heal = 3
set /a health = 500
timeout /t 2 /nobreak >NUL
if %col% == 1 color b0
if %col% == 2 color f0
if %col% == 3 color c0
goto :game
:game
cls
set /a nonpro = %dam%
echo Round %turn%
echo Cash: %cash%
echo Opponent Damage: %dam%
echo Your Protection: %attack%
echo Health: %health%
echo.
echo STATS
echo Basic Troops: %basic%
echo Heavy Troops: %heavy%
echo Sniping Troops: %snip%
echo TOTAL: %total%
echo.
echo.
echo [0] Concede
echo [1] Play Round
echo [2] Recruitment
echo [3] Heal (Heals left: %heal%)
set/p "gamin=>"
if %gamin% == 0 goto lose
if %gamin% == 1 goto play
if %gamin% == 2 goto shop
if %gamin% == 3 goto healtime
goto :game
:play
cls
echo YOU PROTECT!
timeout /t 2 /nobreak >NUL
echo %attack% PROTECTED
timeout /t 3 /nobreak >NUL
echo.
echo THEY ATTACK!
timeout /t 3 /nobreak >NUL
set /a nonpro -= %attack%
if "%nonpro%" LSS "1" set /a nonpro = 0
set /a health -= %nonpro%
echo -%nonpro% HEALTH!
if "%health%" LSS "1" goto :lose
if "%round%" GTR "50" goto :win
set /a round += 1
set /a dam += %random% %% 20
set /a cash += %random% %% 100
goto :game
:shop
cls
echo Recruitment
echo.
echo [0] Leave
echo [1] Basic Troop (-50 Cash, +15 Protection)
echo [2] Heavy Troop (-100 Cash, +40 Protection)
echo [3] Sniping Troop (-70 Cash,+25 Protection)
set /p "shope=>"
if "%shope%" == "0" goto :game
if "%shope%" == "1" goto :buy1
if "%shope%" == "2" goto :buy2
if "%shope%" == "3" goto :buy3
goto :shop
:buy1
if "%cash%" LSS "50" goto :game
set /a cash -= 50
set /a attack += 15
goto :game
:buy2
if "%cash%" LSS "100" goto :game
set /a cash -= 100
set /a attack += 40
goto :game
:buy3
if "%cash%" LSS "70" goto :game
set /a cash -= 70
set /a attack += 25
goto :game
:lose
REM When the player loses, run this code
goto :game
:win
REM When the player wins, run this code
goto :game
Also, your shop doesn't work. Also also I tested your code I modified and it does work
I am trying to use For Loops that will start and end based on values entered by user in batch. However, when using the user input variables, the loop fail to work. May I know what have I done wrong and how do I correct it? Thanks in advance!
P.S. I have tried both ! and %
Here's the my source code which shows the for loop which is having problem:
setlocal EnableDelayedExpansion
set /p sy="Enter start year (e.g. 2020): "
set /p sm="Enter start month (e.g. 08): "
set /p ey="Enter end year (e.g. 2020): "
set /p em="Enter end month (e.g. 08): "
echo ***LIST OF MISSING FILES FROM %sm% %sy% to %em% %ey%*** > checkFile_%SUBFILENAME%.txt
for /L %%y in (%sy%,1,%ey%) do (
for /L %%m in (1,1,%maxMonth%) do (
if %%m leq 9 set month=0%%m
if %%m gtr 9 set month=%%m
if %%y equ %sy% if !month! leq %sm% (
goto :continue
)
if %%y equ %ey% if !month! equ %em% (
goto :breakloop
) else (
call :DaysOfMonth %%y !month!
set maxDay=!errorlevel!
echo Days Of Month !month!: !maxDay!
Here's the full script:
setlocal EnableDelayedExpansion
set maxHour=23
set maxMonth=12
set missing=0
set /p sy="Enter start year (e.g. 2020): "
set /p sm="Enter start month (e.g. 08): "
set /p ey="Enter end year (e.g. 2020): "
set /p em="Enter end month (e.g. 08): "
set CUR_YYYY=%date:~10,4%
set CUR_MM=%date:~4,2%
set CUR_DD=%date:~7,2%
set CUR_HH=%time:~0,2%
if %CUR_HH% lss 10 (set CUR_HH=0%time:~1,1%)
set CUR_NN=%time:~3,2%
set CUR_SS=%time:~6,2%
set CUR_MS=%time:~9,2%
set SUBFILENAME=%CUR_YYYY%%CUR_MM%%CUR_DD%-%CUR_HH%%CUR_NN%%CUR_SS%
echo ***LIST OF MISSING FILES FROM %sm% %sy% to %em% %ey%*** > checkFile_%SUBFILENAME%.txt
for /L %%y in (%sy%,1,%ey%) do (
for /L %%m in (1,1,%maxMonth%) do (
if %%m leq 9 set month=0%%m
if %%m gtr 9 set month=%%m
if %%y equ %sy% if !month! leq %sm% (
goto :continue
)
if %%y equ %ey% if !month! equ %em% (
goto :breakloop
) else (
call :DaysOfMonth %%y !month!
set maxDay=!errorlevel!
echo Days Of Month !month!: !maxDay!
set missingMonth=0
for /L %%d in (1,1,!maxDay!) do (
if %%d leq 9 set day=0%%d
if %%d gtr 9 set day=%%d
for /f "tokens=1*" %%i in ('PowerShell -Command "& {Get-Date "!day!/!month!/%%y" -format "ddd_MMM_dd"}"') do (
for /L %%f in (0,1,!maxHour!) do (
if %%f leq 9 set hour=0%%f
if %%f gtr 9 set hour=%%f
if not exist "%%i_!hour!_00_00_%%y.enf" (
echo Missing: %%i_!hour!_00_00_%%y.enf
echo Missing: %%i_!hour!_00_00_%%y.enf >> checkFile_%SUBFILENAME%.txt
set /A missing = missing+1
set /A missingMonth = missingMonth+1
)
)
)
)
)
echo NUMBER OF FILES MISSING FOR !month!: !missingMonth!
echo ***NUMBER OF FILES MISSING FOR !month!: !missingMonth!*** >> checkFile_%SUBFILENAME%.txt
echo. >> checkFile_%SUBFILENAME%.txt
:continue
)
)
:breakloop
echo TOTAL NUMBER OF FILES MISSING FROM %sm% %sy% to %em% %ey%: %missing%
echo. >> checkFile_%SUBFILENAME%.txt
echo ***TOTAL NUMBER OF FILES MISSING FROM %sm% %sy% to %em% %ey%*** >> checkFile_%SUBFILENAME%.txt
pause
:DaysOfMonth Year Month
setlocal DisableDelayedExpansion
set /a "yy = %~1, mm = 100%~2 %% 100"
set /a "n = 30 + !(((mm & 9) + 6) %% 7) + !(mm ^ 2) * (!(yy %% 4) - !(yy %% 100) + !(yy %% 400) - 2)"
endlocal &exit /b %n%
I have a file that contains time-stamped lines of text. I need to search for lines that start at a specific time and end at a specific time. I already have the times needed stored in variables. I need to be able to break up the line and the time into tokens, i believe, and search for tokens that are geq "start time" and leq "stop time". I know this requires a FOR loop, but I'm not sure how to break this up. (Also , I have found that 8 and 9 fail when used for inputs. I am working on this, I think by hr_start+100 and hr_stop+100 before compare and -100 after compare, etc.) Any improvements on this are appreciated. My goal is a completely error-free interface.
:time_begin
cls
echo.
echo (Use 24-hour clock)
echo.
:hr_start
set /a hr_start=0
set /p hr_start=What hour to start?
if "%hr_start%"=="b" goto day
if %hr_start% geq 0 (
if %hr_start% leq 23 (
if %hr_start% lss 10 set hr_start=0%hr_start%) else (
echo Invalid hour
goto hr_start))
:min_start
set /a min_start=0
set /p min_start=What minute to start?
if "%min_start%"=="b" goto hr_start
if %min_start% geq 0 (
if %min_start% leq 59 (
if %min_start% lss 10 set min_start=0%min_start%) else (
echo Invalid minute
goto min_start))
:sec_start
set /a sec_start=0
set /p sec_start=What second to start?
if "%sec_start%"=="b" goto min_start
if %sec_start% geq 0 (
if %sec_start% leq 59 (
if %sec_start% lss 10 set sec_start=0%sec_start%) else (
echo Invalid second
goto sec_start))
echo.
echo.
:hr_stop
set /a hr_stop=23
set /p hr_stop=What hour to stop?
if "%hr_stop%"=="b" goto sec_start
if %hr_stop% geq 0 (
if %hr_stop% leq 23 (
if %hr_stop% lss 10 set hr_stop=0%hr_stop%) else (
echo Invalid hour
goto hr_stop))
:min_stop
set min_stop=59
set /p min_stop=What minute to stop?
if "%min_stop%"=="b" goto hr_stop
if %min_stop% geq 0 (
if %min_stop% leq 59 (
if %min_stop% lss 10 set min_stop=0%min_stop%) else (
echo Invalid minute
goto min_stop))
:sec_stop
set /a sec_stop=59
set /p sec_stop=What second to stop?
if "%sec_stop%"=="b" goto min_stop
if %sec_stop% geq 0 (
if %sec_stop% leq 59 (
if %sec_stop% lss 10 set sec_stop=0%sec_stop%) else (
echo Invalid second
goto sec_stop))
echo.
set start_disp=%hr_start%:%min_start%:%sec_start%
set stop_disp=%hr_stop%:%min_stop%:%sec_stop%
echo Start time is %start_disp%.
echo Stop time is %stop_disp%.
echo.
:compare
set start_hr=%hr_start%*10000
set /a start_min=%min_start%*100
set /a stop_hr=%hr_stop%*10000
set /a stop_min=%min_stop%*100
set /a start_time=%start_hr% + %start_min% + %sec_start%
set /a stop_time=%stop_hr% + %stop_min% + %sec_stop%
if %stop_time% leq %start_time% (
echo End time must be at least one second after start time
pause
goto time_begin)
:time_confirm
echo.
set start_disp=%hr_start%:%min_start%:%sec_start%
set stop_disp=%hr_stop:~-2%:%min_stop%:%sec_stop%
echo Start time is %start_disp%.
echo Stop time is %stop_disp%.
echo.
set corr_time=blank
set /p corr_time=Times are correct?
if /i "%corr_time%"=="y" goto summary
if /i "%corr_time%"=="n" goto time_begin
goto time_confirm
As you can see, I have two ways I could search: an integer using hour, minute, and second, or a string using %start_disp% and %stop_disp%. Here is a sample line, and all lines follow the same pattern exactly up to this point in the line; after the final ], the pattern varies:
2013/10/30 00:00:13 [501014]CODELINE_INDICATION_MSG 192.168.013.254:5501 TX 41 bytes
solution with sed for Windows:
input file is sorted already:
sed -n "\#START TIME#,\#STOP TIME#p" input.txt>output.txt
input file is not sorted:
sort input.txt | sed -n "\#START TIME#,\#STOP TIME#p" >output.txt
example for a sorted file:
sed -n "\#2013/10/30 00:00:13#,\#2013/11/30 00:00:13#p" input.txt>output.txt
I'm trying to get to calculate the Ackermann function. A description of what I'm trying to achieve is at http://rosettacode.org/wiki/Ackermann_function.
Using the test script, Test 0 4 gives me 5 which is correct. However Test 1 4 gives 5 not 6, and Test 2 4 gives 5 instead of 11.
Where am I going wrong?
::echo off
set depth=0
:ack
if %1==0 goto m0
if %2==0 goto n0
:else
set /a n=%2-1
set /a depth+=1
call :ack %1 %n%
set t=%errorlevel%
set /a depth-=1
set /a m=%1-1
set /a depth+=1
call :ack %m% %t%
set t=%errorlevel%
set /a depth-=1
if %depth%==0 ( exit %t% ) else ( exit /b %t% )
:m0
set/a n=%2+1
if %depth%==0 ( exit %n% ) else ( exit /b %n% )
:n0
set /a m=%1-1
set /a depth+=1
call :ack %m% %2
set t=%errorlevel%
set /a depth-=1
if %depth%==0 ( exit %t% ) else ( exit /b %t% )
I use this script to test it
#echo off
cmd/c ackermann.cmd %1 %2
echo Ackermann of %1 %2 is %errorlevel%
A sample output, for Test 1 1, gives:
>test 1 1
>set depth=0
>if 1 == 0 goto m0
>if 1 == 0 goto n0
>set /a n=1-1
>set /a depth+=1
>call :ack 1 0
>if 1 == 0 goto m0
>if 0 == 0 goto n0
>set /a m=1-1
>set /a depth+=1
>call :ack 0 0
>if 0 == 0 goto m0
>set/a n=0+1
>if 2 == 0 (exit 1 ) else (exit /b 1 )
>set t=1
>set /a depth-=1
>if 1 == 0 (exit 1 ) else (exit /b 1 )
>set t=1
>set /a depth-=1
>set /a m=1-1
>set /a depth+=1
>call :ack 0 1
>if 0 == 0 goto m0
>set/a n=1+1
>if 1 == 0 (exit 2 ) else (exit /b 2 )
>set t=2
>set /a depth-=1
>if 0 == 0 (exit 2 ) else (exit /b 2 )
Ackermann of 1 1 is 2
Change line 27 above from
call :ack %m% %2
to
call :ack %m% 1
What is the scope of your variables m and n?
You set values within one call to :ack, and then recursively call again, setting values. Do you overwrite them? In Stack-based languages such as C and Java, local variables are fine, each level of recursion gets new variables. What happens in cmd?