I have a batch file and within that batch file I need to run one of two commands depending on time of my server.
If the time is between 22:00:00 and 03:30:00 -- xcopy /Y a\1.txt c\1.txt
If the time is before or after this range -- -- xcopy /Y b\1.txt c\1.txt
This will use xcopy to switch a file back and forth depending on the time.
I know this is easy but my brain just won't work atm lol
Edit:
Went with 22:00 and 4:00... this is what I came up with but it doesn't seem like the best way...
set current_time=%time:~0,5%
if "%current_time%" lss "22:00" goto daycycle
if "%current_time%" gtr " 4:00" goto daycycle
echo Do this between 10pm and 4am
goto continue
:daycycle
echo Do this before 10pm and after 4am
:continue
#echo off
setlocal enableextensions disabledelayedexpansion
set "now=%time: =0%"
set "task=day"
if "%now%" lss "03:30:00,00" ( set "task=night" )
if "%now%" geq "22:00:00,00" ( set "task=night" )
call :task_%task%
endlocal
exit /b
:task_day
:: do daily task
goto :eof
:task_night
:: do nightly task
goto :eof
EDITED - The previous code should work under the conditions in the original question. But will fail in different time configurations. This should solve the usual problems
#echo off
setlocal enableextensions disabledelayedexpansion
call :getTime now
set "task=day"
if "%now%" lss "03:30:00,00" ( set "task=night" )
if "%now%" geq "22:00:00,00" ( set "task=night" )
call :task_%task%
echo %now%
endlocal
exit /b
:task_day
:: do daily task
goto :eof
:task_night
:: do nightly task
goto :eof
:: getTime
:: This routine returns the current (or passed as argument) time
:: in the form hh:mm:ss,cc in 24h format, with two digits in each
:: of the segments, 0 prefixed where needed.
:getTime returnVar [time]
setlocal enableextensions disabledelayedexpansion
:: Retrieve parameters if present. Else take current time
if "%~2"=="" ( set "t=%time%" ) else ( set "t=%~2" )
:: Test if time contains "correct" (usual) data. Else try something else
echo(%t%|findstr /i /r /x /c:"[0-9:,.apm -]*" >nul || (
set "t="
for /f "tokens=2" %%a in ('2^>nul robocopy "|" . /njh') do (
if not defined t set "t=%%a,00"
)
rem If we do not have a valid time string, leave
if not defined t exit /b
)
:: Check if 24h time adjust is needed
if not "%t:pm=%"=="%t%" (set "p=12" ) else (set "p=0")
:: Separate the elements of the time string
for /f "tokens=1-5 delims=:.,-PpAaMm " %%a in ("%t%") do (
set "h=%%a" & set "m=00%%b" & set "s=00%%c" & set "c=00%%d"
)
:: Adjust the hour part of the time string
set /a "h=100%h%+%p%"
:: Clean up and return the new time string
endlocal & if not "%~1"=="" set "%~1=%h:~-2%:%m:~-2%:%s:~-2%,%c:~-2%" & exit /b
Try this:
#echo off
set hour=%time:~0,2%
set min=%time:~3,2%
if %hour% GEQ 22 (
xcopy /Y a\1.txt c\1.txt
) ELSE (
if %hour% LEQ 3 (
if %hour% EQU 3 if %min% GTR 30 (
xcopy /Y b\1.txt c\1.txt
goto :END
)
xcopy /Y a\1.txt c\1.txt
) ELSE (
xcopy /Y b\1.txt c\1.txt
goto :END
)
)
:END
And I'm rather sure that will do what you want. Manual if statements for the win! Note it would be a lot easier if it was 22:00 to 4:00 or 3:00. I had to incorperate the :30 minute checker.
But yea, it might not work, so just check it before you put it up on your server.
Monacraft.
What should work:
#echo off
:loop
set hour=%time:~0,2%
set min=%time:~3,2%
cls
ECHO %hour%
ECHO %min%
ECHO This %I%
IF %hour% == 14 GOTO Test2
goto loop
:Test2
IF %min% == 58 GOTO YUP
IF %min% == 59 GOTO LATE
Goto loop
:YUP
SET I=0
GOTO loop
:LATE
SET I=NOPE
GOTO loop
Related
With below code I'm struggling to print calculation for each value in a given list. Currently it prints total combined time for both users, I want to echo individual time for each user which is listed in 2nd row of this code.\
Any help will be appreciated.
#Echo off
For %%U in (a3rgcw shukla) Do (
PushD "H:\Syslogs\" ||(Echo couldn't find dir & Pause & Exit /B 1)
Set "TotalSecs=0"
For %%F in ("*%U%*.txt") Do For /F "delims=" %%A in ('
findstr /I "system.log.created End.of.session" "%%F"
') Do (
Set "Flag="
Echo=%%A|findstr /I "system.log.created" 2>&1>Nul && Set "Flag=Start"
if defined Flag (
FOR /F "tokens=11" %%T in ("%%A") Do Call :TimeToSecs Start "%%T"
) Else (
FOR /F "tokens=8" %%T in ("%%A") Do Call :TimeToSecs Stop "%%T"
)
)
Echo TotalDuration for %%U:%TotalDur%
)
Echo:
PopD
Goto :Eof
:TimeToSecs
Set "%1_HMS=%~2"
Echo:%~2|Findstr "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]" 2>&1>Nul || (Echo wrong format %2&Goto :Eof)
For /F "tokens=1-3 delims=:" %%H in ("%~2"
) Do Set /A "%1=(1%%H-100)*60*60+(1%%I-100)*60+(1%%J-100)"
If %1 neq Stop Goto :Eof
Set /A "Diff=Stop-Start,TotalSecs+=Diff"
Call :Secs2HMS Dur %Diff%
Call :Secs2HMS TotalDur %TotalSecs%
::Echo Session from %Start_HMS% to %Stop_HMS% Duration:%Dur% TotalDuration:%TotalDur%
Goto :Eof
:Secs2HMS var value
setlocal
set /a "HH=%2/3600,mm=(%2-HH*3600)/60+100,ss=%2 %% 60+100"
Set "HHmmss= %HH%:%mm:~-2%:%ss:~-2%"
endlocal&set "%1=%HHmmss:~-10%
Goto :Eof
Current output:
TotalDuration for a3rgcw: 7:15:00
TotalDuration for shukla: 7:15:00
Desired output:
TotalDuration for a3rgcw: 5:15:00
TotalDuration for shukla: 2:00:00
Sample file named shukladfdf for 2nd user:
sdsdf system log created on ghg Thursday, 9 August 2018, 20:30:45 on India
Standard Time
dfg
drdwewed
end of session as 9 August 2018, 22:30:45 on India Standard Time
#Echo off
Setlocal
PushD "H:\Syslogs\" ||(Echo couldn't find dir & Pause & Exit /B 1)
For %%U in (a3rgcw shukla) Do (
Set "TotalDur="
Set "TotalSecs=0"
For %%F in ("*%%U*.txt") Do For /F "delims=" %%A in ('
findstr /I "system.log.created End.of.session" "%%F"
') Do (
Set "FileName=%%F"
Set "Flag="
Echo=%%A|findstr /I "system.log.created" 2>&1>Nul && Set "Flag=Start"
if defined Flag (
FOR /F "tokens=11" %%T in ("%%A") Do Call :TimeToSecs Start "%%T"
) Else (
FOR /F "tokens=8" %%T in ("%%A") Do Call :TimeToSecs Stop "%%T"
)
)
Set "UsrName=%%U: "
Call :Print UsrName
)
Echo:
PopD
Goto :Eof
:Print
If /i "%~1" == "UsrName" (
Echo TotalDuration for %UsrName:~,10% %TotalDur%
) else If /i "%~1" == "FileName" (
Echo Session (%FileName%^) from %Start_HMS% to %Stop_HMS% Duration:%Dur% TotalDuration:%TotalDur%
)
Goto :Eof
:TimeToSecs
Set "%1_HMS=%~2"
Echo:%~2|Findstr "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]" 2>&1>Nul || (Echo wrong format %2&Goto :Eof)
For /F "tokens=1-3 delims=:" %%H in ("%~2"
) Do Set /A "%1=(1%%H-100)*60*60+(1%%I-100)*60+(1%%J-100)"
If %1 neq Stop Goto :Eof
Set /A "Diff=Stop-Start,TotalSecs+=Diff"
Call :Secs2HMS Dur %Diff%
Call :Secs2HMS TotalDur %TotalSecs%
Call :Print FileName
Goto :Eof
:Secs2HMS var value
setlocal
set /a "HH=%2/3600,mm=(%2-HH*3600)/60+100,ss=%2 %% 60+100"
Set "HHmmss= %HH%:%mm:~-2%:%ss:~-2%"
endlocal&set "%1=%HHmmss:~-10%"
Goto :Eof
Changed %U% to %%U.
Changed Echo TotalDuration for %%U:%TotalDur% to
Call Echo TotalDuration for %%U:%%TotalDur%% which
delays expansion until time of execution, instead of
parse time.
Added missing double quote with 2nd last line to close.
Added Setlocal to top of script as perhaps a 2nd run
of the script in the same CMD session could set
predined variables with values.
Added label :Print to echo the output to avoid
use of delayed expansion.
I am trying to add a time out to Set /p Var1= So far I have only found this piece of code from here.
#echo off
setlocal EnableDelayedExpansion
if "%1" NEQ "" goto %1
del enter.tmp 2>nul >nul
start /b cmd /c %0 :secondThread
:FirstThread
set n=0
echo Enter Text (5 seconds timeout):
:loop
set /a n+=1
ping -n 2 localhost > nul
if !n! LSS 5 (
if not exist entER.tmp goto :loop
< Enter.tmp (
set /p input=
)
echo !input!
) ELSE (
echo Timeout for input
)
exit /b
:secondThread
set /p var=
> enter.tmp echo !var!
exit /b
This piece of code works great except it stops the count down only when the input is entered. I would like the count down to stop when any key is pressed. I don't know if this is possible. Thanks
I am currently making a game that has a persuasion system in it. I had all the code for one of the systems set up, but then I set up 2 more, and it started give me an error that said '(number) was not expected at this time'. when I put in 2 for the second choice, and 3 for the 3rd choice.
The code is like this.
#echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
set name=Quantum
cls
color 0a
Echo King Redwood: So 2000?
pause >nul
echo.
call :colorText 09 "1. 2500"
echo.
call :colorText 0e "2. 3000"
echo.
call :colorText 0c "3. 4000"
echo.
echo 4. 2000
echo.
set /p "purs=Enter:"
if /i %purs% == 1 (
goto CheckB )
if /i %purs% == 2 (
goto CheckY )
if /i %purs% == 3 (
goto CheckR )
if /i %purs% == 4 (
goto Convo )
:CheckB
set bleu=%random:~-2,1%
if %bleu% GTR 10 (
goto CheckB )
if %bleu% LSS 0 (
goto CheckB )
set /a num = 3
set /a reward = 2500
goto Res
:CheckY
set Yel=%random:~-2,1%
if %Yel% GTR 10 (
goto CheckY )
if %Yel% LSS 0 (
goto CheckY )
set /a num = 5
set reward = 3000
goto Res
:CheckR
set red=%random:~-2,1%
if %red% GTR 10 (
goto CheckB )
if %red% LSS 0 (
goto CheckB )
set /a num = 7
set /a reward = 4000
goto Res
:Convo
set /a reward = 2000
Echo %name%: I think that is a reasonable price.
Echo King Redwood: Very well.
Echo King Redwood: We will now take you to make sure you are
echo ready.
pause >nul
:Res
if %bleu% GEQ %num% goto Succeed
if NOT %bleu% GEQ %num% goto Fail
:Succeed
Echo %name%: I think that the struggles for such a long trip will be more then that
Echo %name%: How about %reward%?
Echo King Redwod: OK %reward% will work.
pause >nul
goto end
:Fail
Echo %name%: I think that you can give me %reward%.
Echo %name%: You know, for the struggles that there will be along the way.
echo If 2000 isn't good enough for you, I'll just have someone else do it.
pause >nul
:end
exit
:colorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1i
First, make sure to close the FOR loop by putting a ) before :CheckB.
For the 'was not expected at this time' error, you're sometimes comparing an empty variable to something. For example, by following CheckY, you set Yel, then proceed to Res and check Bleu, which is empty because it hasn't been set. You're putting nothing next to the binary GEQ operator, and that's why it's complaining.
Tip: to debug, try inserting ECHO statements like this:
:Res
echo bleu=%bleu%,num=%num%
Another problem: when using SET, do not surround the = by spaces. SET /a will work with spaces around =, just because of the nature of /a, but plain SET will not. Well, it will append your variable name with a space and prepend your value with a space, which is not what you want.
Another tip: you can constrain what RANDOM returns through SET /a and the modulus operator, like this.
SET /a red=%random% %% 11
This will set red to a number between 0 and 10, so there is no need for the substrings and goto routines you're using after picking your random number.
Also, consider using EXIT /b to exit the batch file and not the whole CMD environment.
Good Afternoon!
Long time reader, first time poster! I have been having a lovely time trying to modify a working batch file to account for variability. The situation is that I have a variable-size text document that normally would be able to be split into sections of 252 lines. The code below worked like a champ:
#echo off & setlocal EnableDelayedExpansion
set param=%*
if not defined param (
echo.
echo. Usage: batchsplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
goto :EOF
)
for %%j in ("%param%") do (
set name=%%~dpnj
set ext=%%~xj
)
for /F %%j in ('type "%param%" ^| find /V /C ""') do set Full=%%j
set /A Split=%Full%/252
for /L %%G in (1,1,%Split%) do type nul > "%name%_%%G%.new"
set X=1
set N=1
set Q=1
set limit = 252
for /F "tokens=1* delims=]" %%j in ('type "%param%" ^| find /V /N ""') do (
set /A N+=1
set /A Q+=1
echo.%%k>> "%name%_!X!%.new"
if !Q! gtr 252 (
set /A X+=1
set /A Q=1
) else if !N! gtr Full (goto theend
)
)
:theend
echo split into %split% files with 252 lines each
rem pause
However, there were some changes to the formatting of the text, and now instead of four pages of 63 lines per split file, it can be completely variable. The only constant is this final line, which precedes the remaining space for a 63 line page:
ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
Note that there is a single space in front of it, as well as multiple spaces, a colon, and underscore characters. Being the meathead that I am, I thought I could insert an if-then statement into the for loop to trigger the batch to split to the next page. However, I could be further from that right now. This is the code I have been smashing my head with:
rem #echo off & setlocal EnableDelayedExpansion
setlocal EnableDelayedExpansion
set param=%*
if not defined param (
echo.
echo. Usage: textsplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
goto :EOF
)
for %%j in ("%param%") do (
set Name=%%~dpnj
set ext=%%~xj
)
for /F %%j in ('type "%param%" ^| find /V /C ""') do set Full=%%j
set stopvar= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
set Split=1
echo %stopvar%
set X=1
type nul > "%name%_!X!%.new"
set N=1
set Q=1
set S=0
set L=63
for /F "tokens=1* delims=]" %%j in ('type "%param%" ^| find /V /N ""') do (
set /A N+=1
echo %N%
set /A Q+=1
echo %Q%
echo.%%k>> "%name%_!X!%.new"
if ["%%k%" == "!stopvar!"] (
set /A S+=1
)
if !Q! gtr !L! (
if !S! == 1 (
set /A X+=1
set /A Q=1
type nul > "%name%_!X!%.new"
set /A Split+=1
set S=0
)
else set /A L+=63
else if !N! gtr Full goto theend
)
:theend
echo Split into %split% files!
pause
The premise is that every 63 lines, the stop variable (S) is checked. If it is off (0) then the batch will continue to write for another 63 lines (one page). If the stopvar matches the line that is being read by the for loop, S becomes 1. When the program checks again, it will create a new file and begin writing to that new file. Right now, based on turning off #echo off the hangup is at the for loop. See below:
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>rrtextsplit texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>rem #echo off & setlocal Enabl
eDelayedExpansion
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>setlocal EnableDelayedExpansio
n
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set param=texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>if not defined param (
echo.
echo. Usage: rrtextsplit [device:][pathname]filename
goto :EOF
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set param=texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>if not exist "texttest.txt" (
echo.
echo. File "texttest.txt" not found
goto :EOF
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>for %j in ("texttest.txt") do
(
set Name=%~dpnj
set ext=%~xj
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>(
set Name=C:\Users\theangryasiancp\Desktop\TEXT_Split_Test\texttest
set ext=.txt
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>for /F %j in ('type "texttest.
txt" | find /V /C ""') do set Full=%j
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Full=567
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set stopvar= ON THIS FORM IS C
OMPLETE AND CORRECT AS NOTED:___________________
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Split=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>echo ON THIS FORM IS COMPLETE
AND CORRECT AS NOTED:___________________
ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set X=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>type nul 1>"C:\Users\theangry
asiancp\Desktop\RRRR_Split_Test\texttest_!X!.new"
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set N=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Q=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set S=0
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set L=63
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>
What are your thoughts? Where am I going wrong with the batch? I wish I could use something different, but alas I cannot, for internal company reasons. Thanks for your help!
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "name=q23396663"
SET "ext=.txt"
SET /a pagelength=10
SET "targetstring= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________"
SET /a filenum=0
SET /a linecount=pagelength + 1
FOR /f "tokens=1*delims=]" %%a IN (
'find /v /n "" "%name%%ext%"') DO (
IF !linecount! GEQ %pagelength% (
SET /a linecount=0
SET /a filenum+=1
)
>>U:\%name%_!filenum!.new ECHO(%%b
IF "%%b"=="%targetstring%" SET /a linecount=pagelength
SET /a linecount+=1
)
GOTO :EOF
For testing purposes, I set up a file q23396663.txt containing your trigger data. I've left the destination directory as U:\ which suits me, and the pagelength at 10 which makes my testing easier.
#echo off
setlocal EnableDelayedExpansion
REM ------------------THIS SECTION SPECIFIES THE FILE-------------------------
set param=%*
if not defined param (
echo.
echo. Usage: filesplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
GOTO :EOF
)
for %%j in ("%param%") do (
set name=%%~dpnj
set ext=%%~xj
)
ECHO SPLITTING %name%.%ext% .................
REM ----------------THIS SECTION SETS THE VARIABLES---------------------------
set "trigger= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________"
set /a pagelength=63
set /a filenum=0
set split=1
set /a linecount=pagelength
set stopvar=0
REM ------------------THIS SECTION IS THE FOR LOOP----------------------------
FOR /f "skip=2 tokens=1* delims=]" %%a IN (
'find /v /n "" "%name%%ext%"') DO (
SET /a linecount-=1
IF !linecount! LEQ 0 (
IF !stopvar! EQU 1 (
SET /a "linecount=pagelength"
SET /a filenum+=1
SET /a split+=1
SET /a stopvar-=1
) else set /a "linecount=pagelength"
)
echo.%%b>> "%name%_!filenum!.new"
IF "%%b"=="%trigger%" (
set /a "stopvar+=1"
REM THIS TRIGGERS TO CHANGE OUTPUT
set /a linecount+=1
REM THIS WILL ADJUST THE OUTPUT EOF
)
)
REM ----------------THIS SECTION ENDS THE FOR LOOP----------------------------
ECHO Split into %split% files!
ping 1.1.1.1 -n 1 -w 2500 > nul
REM THIS PAUSES THE BATCH FOR A SEC
As I posted in the comment above, this is just a variation of the first answer that accounts for blank spaces if they are needed to keep the output files from having unnecessary whitespace on top. This is especially helpful when a print manager is just spitting out whitespace until the end of the page before starting the next part instead of going straight to the next portion.
:Life
set /a R=%random%%%50+1
echo %random% >> %R%.bat
set /a t=%time:~6,-3%
If %t% geq 10 (
set /a t=%t%-10
) else (
set /a t=%t%+10
)
:wait
If %time:~6,-3% neq %t% goto :Wait
:death
set /a K=%random%%%50+1
del /Q %K%.bat
:disease
set /a D=%random%%%150+1
If %D% EQU 150 del /Q *.bat (
goto Life
) else (
If %D% EQU 150 echo On Error Resume Next > temp.vbs
If %D% EQU 150 echo MsgBox "Disease Killed The Biome", vbInformation + vbSystemModal + vbOKOnly, "Life.exe" >> temp.vbs
If %D% EQU 150 cscript temp.vbs
If %D% EQU 150 del temp.vbs
goto Life
)
:EOF
So my issue is the timer engine. The counter itself contains 00–59 but the other is 0–59 so when the ticker hits a number and it has a value of 9 or less it'll skip them on the next passover because they don't have 09 (etc.), is there a way where I can set the code to other ticker to stay at 59 the whole time?
It would be easier to read, if you could format your code a little bit.
To solve your current problem, you could use the time to decimal trick.
set /a t=1%time:~6,-3%-100
Else you got problems with the times 08 and 09, because of the leading zero, it assumes it should be an octal value and fails.
And in the wait-loop you could use the same way
:wait
set /a now=1%time:~6,-3%-100
If %now% neq %t% goto :Wait
But to wait a time it is better to use the way,
ping localhost -n [sec]+1 > NUL
because the your way consumes the 100% cpu (one core).