How to check the format of a time using batch script? - time

is there any way in batch script to check a format of a time?
Ex.
I have a scenario with a wrong format of time:
set tm=431:00:00
I want to check it if tm is a time with a format HH:MM:SS.
if %tm% == %format% (
do something ) else (
do nothing )
Is it possible in batch script to do some checking like that?
Please spare with me. Thanks.

set origTime=%time%
echo %tm% | time > nul
if errorlevel 1 (
echo Time format is invalid
)
echo %origTime% | time > nul
EDIT New method as requested
The following code check that:
- The time have 3 parts separated by colon
- Each part be a number
- The multiplication of the 3 numbers be not zero
for /F "tokens=1-3 delims=:" %%a in ("%tm%") do set HH=%%a& set MM=%%b& set SS=%%c
rem Set ERRORLEVEL to zero:
ver > nul
set /A result=%HH%*%MM%*%SS% > nul
if errorlevel 1 echo Bad format
if %result% == 0 echo Bad format
Previous example may give you more ideas on how check for other cases...

One easy option is to use FINDSTR /R to do a regular expression check if the time has the right number of digits.
set tm=43:00:00
echo %tm%| findstr /R "^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"
if errorlevel 1 (
echo Invalid time!
) else (
echo OK
)
The problem with that approach is that FINDSTR only has limited regex support, so you can't really tell with the above if the time actually makes sense (e.g. if hour is 25...)
You could improve the script by doing a few separate checks. For example: if the hour's first digit is [2] then the second digit must be [0-3]. However, for all that effort, I'd rather just call out to a simple PowerShell script to do check if the time is correct and use the output from the PS script in your batch file.

Related

Filtering for multiple results in batch using IF

I was writing a batch file replicating CMD but more customized. What I am trying to do is scan %input% for multiple different results leading to different actions. To help you envision what I mean, I tried doing this:
set /p input="%cd%>"
if "%input%" == "cls" (
GOTO reset
) else (
if "%input%" == freespace (
GOTO freespace
) else (
title %input%
%input%
GOTO A
Which just crashes the CMD window running the batch file. Is there anyway I can sort for these two responses (or possibly more) using IF statements? I realize this is SIMILAR to other questions called "using multiple if statements in batch" but they are just not the same format I am trying to put the IF statements in.
You appear to be running your batch by clicking on it, which means that you will not see error messages. It's better to run batch from the command-prompt so that the messages will be visible and persistent.
There are at least two problems with the code you have presented.
The first is that you have not closed the parentheses for the else clauses so there are two pending close-parentheses at the end of the batch.
format:
if x=y (dothis
) else (
if p==q (dosomethingelse
) else (
dosomethingelseentirely
)
)
The second problem is that if is very literal with a string-match. It includes the quotes in the strings-to-be-matched, so
if "%input%" == freespace (
can never be true as input is quoted but freespace is not (unlike cls in your first if)
BTW - if /i ... will perform a case-insensitive comparison.
You don't need multiple if commands to filter multiple results in this particular problem. This is the way I would do it:
#echo off
setlocal
:A
echo/
set "input="
set /p "input=%cd%>"
call :%input% 2> NUL
if errorlevel 1 echo "%input%" is not recognized as a command...
goto A
:cls
echo Reset command, parameters: "%*"
exit /B 0
:freespace
echo FreeSpace command, parameters: "%*"
exit /B 0
In this method a call :%input% command is directly executed, so if the label exists, then the corresponding code run; otherwise, the call :nolabel command returns an ERRORLEVEL equal 2.
Each one of the subroutines ends with exit /B 0 command, so in these cases the ERRORLEVEL is zero.
If you have any doubt about a particular command, I encourage you the review its command /? help screen or search the web looking for a more extensive description...

Allowing multiple choice selections for users using batch file [duplicate]

This question already has answers here:
Multiple choices menu on batch file?
(13 answers)
Closed 8 years ago.
I want to create a windows batch scripting whereby it allows the user to enter multiple choices at one go, and then after that the program will runs.
With reference to this website (Multiple choices menu on batch file?), I get to know it somehow works to allow multiple selection. However, this is in bash scripting. For example...
#echo off
setlocal enabledelayedexpansion
echo Which would you like to use?
echo 1. Hello.txt
echo 2. Byebye.txt
echo 3. ThisIsText.txt
echo 4. MyBatchScript.txt
echo 5. All
set /p op=Type the numbers of the names you want to use (separated by commas with no spaces. E.g: 1,3,2):
Until here, it works by prompting users to select one or more choices.
for /f "delims=, tokens=1-5" %%i in ("op") do (
set i=%%i
set j=%%j
set k=%%k
set l=%%l
set m=%%m
)
However, until here, I realised that the choices would be stored into a variable "op" and this would then be in i. And basically, j, k, l and m are not used. I'm not sure if I interpreted it wrongly. Hopefully I did not interpret the coding wrongly.
So for what I want is that...
When the user selects only 1 options,
It will insert the "Hello.txt" into a command (e.g.)
echo This is complicated > Hello.txt
But if the user selects more than 1 options (for example, user typed 1,2),
then it will insert
echo This is complicated > Hello.txt
echo This is complicated > Byebye.txt
And if the user selects option '5', it cannot be entered along with other numbers (since it is ALL). Then it will echo the This is complicated > Byebye.txt , Hello.txt , etc
Is there anyway to do it using batch scripting?
Edit: Can anyone explain this to me? I tried finding different websites but I still don't get it. Sorry, I am new to writing batch scripts. So the understanding of it is still not deep. Disclaimer: This is the coding I got from the website I mentioned above.
if %i%X neq X set last=1b & goto %i%
:1b
if %j%X neq X set last=2b & goto %j%
:2b
if %k%X neq X set last=3b & goto %k%
:3b
if %l%X neq X set last=4b & goto %l%
:4b
if %m%X neq X set last=%m% & goto %m%
goto next
:1
::Put the code for doing the first option here
goto %last%
:2
::Put the code for doing the second option here
goto %last%
:3
::Put the code for doing the third option here
goto %last%
:4
::Put the code for doing the fourth option here
goto %last%
:5
::Put the code for doing the fifth option here
goto %last%
I do not get how this helps to run multiple command. If I input 1,2,3 into the field, how does it gets me to part where I can run it all together?
You may make good use of the fact that the standard separators for items in flat FOR command (no /F option) are spaces, commas, semicolons and equal-signs:
#echo off
setlocal enabledelayedexpansion
echo Which would you like to use?
echo 1. Hello.txt
echo 2. Byebye.txt
echo 3. ThisIsText.txt
echo 4. MyBatchScript.txt
echo 5. All
:getOptions
set /p "op=Type the numbers of the names you want to use (separated by commas OR spaces): "
if "%op%" equ "" goto getOptions
if %op% equ 5 set op=1,2,3,4
for %%a in (%op%) do (
echo Process option %%a
call :option-%%a
)
goto :EOF
:option-1
echo 1. Hello.txt
exit /B
:option-2
echo 2. Byebye.txt
exit /B
:option-3
echo 3. ThisIsText.txt
exit /B
:option-4
echo 4. MyBatchScript.txt
exit /B
You wrote, you tried ('%op'), ("%op"), (%op) and variations.
It should be: ("%op%")
Only forvariables and Commandline-Parameters use <Percent><char> syntax.
op is a "normal" variable and it is used <Percent><name><Percent>: %op%

Batch file setting variable in if/else statement in For Loop

I'm trying to create a batch file that generates a custom AVIsynth script per each file. Right now the batch file is set to execute from within the folder where the video files exist. What I need to do is get the creation time of the file to generate a timecode burn in. I have no problem getting the info I need. However, if the file was created in the afternoon I need it to be in 24hr time. For example, 2pm needs to display as 14.
I have a working if statement that creates a newth variable that adds 12 if need be. However, if it doesn't need it the variable persists. On each subsequent iteration of the loop the variable doesn't change.
My example. I have two files the first was created at 2pm the other at 12pm. The 2pm file is read first and the newth variable becomes 14. So far so good. On the next file the newth variable should become 12 but instead remains 14. How do I fix this?
#Echo Off & CLS
SetLocal EnableDelayedExpansion
For /F %%a In ('dir *.mpg /b') Do (
ECHO Processing "%%a"
echo %%~ta
set time=%%~ta
set th=!time:~11,2!
set tm=!time:~14,2!
set era=!time:~17,2!
echo !era!
if "!era!"=="PM" (
if !th! LSS 12 ( set /a newth=!th!+12 )
) else ( set /a newth=!th!)
echo !newth!
echo //AviSynth Test Script >scripts/%%a.avs
echo DirectshowSource^("%%~fa"^)>>scripts/%%a.avs
echo LanczosResize^(720,400^) >>scripts/%%a.avs
echo ShowSMPTE^(^) >>scripts/%%a.avs
ECHO Back to Console
Pause
)
It's a little messy because I've been using echo for debugging. But hopefully the problem is clear.
Here is a method with Wmic - Wmic is in XP pro and above.
#Echo Off & CLS
SetLocal EnableDelayedExpansion
For /F "delims=" %%a In ('dir *.mpg /b') Do (
ECHO Processing "%%a"
set "file=%cd%\%%a"
set "file=!file:\=\\!"
WMIC DATAFILE WHERE name="!file!" get creationdate|find ".">file.tmp
for /f %%a in (file.tmp) do set dt=%%a
set tm=!dt:~8,2!:!dt:~10,2!:!dt:~12,2!
del file.tmp
echo !tm!
echo //AviSynth Test Script >scripts/%%a.avs
echo DirectshowSource^("%%~fa"^)>>scripts/%%a.avs
echo LanczosResize^(720,400^) >>scripts/%%a.avs
echo ShowSMPTE^(^) >>scripts/%%a.avs
ECHO Back to Console
Pause
)
There are a few problems with your code. The major one is this sequence
if "!era!"=="PM" (
if !th! LSS 12 ( set /a newth=!th!+12 )
) else ( set /a newth=!th!)
With your first filetime "02:xx PM"
th=02, era=PM, so set /a newth=02+12 sets newth=14
With your second filetime "12:xx PM"
th=12, era=PM, so - do nothing, since there's no else action for !th! LSS 12
Hence, newth remains at 14.
So - what's the fix? Since you don't use newth further, we can't say for certain, but it appears you want 24-hour format - 4 digit hhmm.
DANGER, Will Robinson moment number 1:
You are dealing with numbers starring LEADING ZEROES. All well and good except where the value is 08 or 09, which batch bizarrely interprets as OCTAL since it begins 0.
DANGER, Will Robinson moment number 2:
set /a will suppress leading zeroes, so set /a newth=!th! will set newth to 7 for time 07:36 AM - not 07...
So - how to overcome all this?
IF !th!==12 SET th=00
SET th=!th: =0!
if "!era!"=="PM" (set /a newth=1!th!+12
SET newth=!newth:~-2!
) else ( set newth=!th!)
This forces 12 AM to 00 AM and 12 PM to 00 PM
Then replace any spaces with 0 (in case you have leading spaces, not zeroes)
Then, if era is PM, add 100 by stringing 1 before the 2-digit hour number, add 12 and grab the last 2 characters
Otherwise, just use the number in th
Unfortunately, made a little more complicated since you haven't told us whether you use or don't use leading zeroes in your time format. Nevertheless, the incomplete original calculation method is at fault.
DANGER, Will Robinson moment number 3:
time is a MAGIC VARIABLE - and you know what happened to Mickey when he got involved in things better left alone.
If you set time in a batch, then %time% or !time! will return the value you set. If you don't set it, then the value returned will be the system time. Same goes for DATE and a number of similar values (see set /? from the prompt - there's a list at the end)
here's how you can get the time stamp with seconds:
C:\>powershell -command "& {(gwmi -query """select * from cim_datafile where name = 'C:\\file.txt' """).lastModified;}"
C:\>powershell -command "& {(gwmi -query """select * from cim_datafile where name = 'D:\\other.txt' """).creationdate;}"
I've tried with WMIC but still cannot get the time stamp.As you are using Win7 you should have powershell installed by default.

Abnormal behavior of batch script in If else condition

As a beginner in batch file programming, i have created a batch file. Below is the code snippet-
SET INDEX=1
SET CURRJOBS=10
REM TOTALJOBS and CURRJOBS are dynamic but to keep code here, i have put static values to them
SET TOTALJOBS=1000
IF [%CURRJOBS%] LSS [%TOTALJOBS%] (
IF [%INDEX%] GEQ [5] (
SET /A INDEX=0
)
ECHO Started at %date% %time% with %CURRJOBS% jobs>>%CURRDIR%\JobSubmit.log
REM Here is a call to another bat file with Index.
ECHO Finished at %date% %time% with %CURRJOBS% jobs>>%CURRDIR%\JobSubmit.log
SET /A INDEX+=1
GOTO START
)ELSE (
ECHO Finished at %date% %time% with %CURRJOBS% jobs>>%CURRDIR%\JobSubmit.log
)
Now, this code, sometimes work, sometimes not.
however there is some syntax error which might be a cause to behave abnormally. Is there any IDE or online utility to check the syntax of batch file?
What is wrong with above code?
Comparisons in IF command are of two types: string or number. To indicate IF that we want number comparison, the numbers must be written with no additional characters. So, your code should be written this way:
IF %CURRJOBS% LSS %TOTALJOBS% (
IF %INDEX% GEQ 5 (
SET /A INDEX=0
)
When a variable or parameter may have an empty value, it is customary to enclose it between quotes to avoid syntax errors, for example:
IF "%POSSIBLEEMPTYVAR%" NEQ "" (
If the variable have string values, you may use the same format for both check for empty value and do the comparison:
IF "%VARIABLE%" equ "THIS VALUE" GOTO OK
However, if a variable may be empty and you want to compare it as number, both tests must be made.

Win batch: setting variable within nested loop not working

I have a long script that I have condensed to the following lines of code to illustrate the issue I am having. I have tried some suggestion by StackOverflow users to no avail, so hopefully your feedback will help me and future users. NOTE: this code works, except for setting the pdfREP nested variable.
SETLOCAL enabledelayedexpansion
set pdfREP=false
for /f "tokens=1" %%a in ('dir /o /b \\path2document\*.rp?') do (
findstr "," \\path2log\%%a > 1.log
if not errorlevel 0 (
:: do something
)
if errorlevel 0 (
findstr /B /I "p" \\path2document\%%a > 1.log
if errorlevel == 0 (
set pdfREP=true
echo RSP File: %%a >> 2.log
)
)
)
Basically the issue is that in \path2document I have multiple files, and within each I look for a comma. If no comma is found then I want to know if there is a particular letter inside the file's text. If the text is found, the I am setting a previously defined variable to TRUE, instead of FALSE. However, the "if errorlevel == 0" can be true if different syntax (%errorlevel%==0,%errorlevel% EQU 0), and it will NOT set the variable pdfREP to TRUE. If the issue is that the variable is not set until after the loop iteration, then how can I use this variable in the rest of my code? I would like to use this variable later on, so setting it is most important. Thanks for any feedback.
Windows batch has an "interesting" way of handling nested variables. This article might help.
Personally, when my batch files get this complex, I switch to a different language. My first choice is generally Python, but if you'd like to stay inside the Microsoft ecosystem, then vbscript or PowerShell would work.
You are misusing the IF command and the errorlevel value.
IF command description indicate that you may directly use in the condition the ERRORLEVEL word followed by a number indicating a given errorlevel. This way, the following two IF commands are right:
if not errorlevel 0 (
:: do something
)
if errorlevel 0 (
However, the following command is bad written:
if errorlevel == 0 (
In this case, you must use !errorlevel! to indicate to take the current errorlevel value after executing the last line:
if !errorlevel! == 0 (
Independently of the above said, this is the way that I would do that:
if not errorlevel 0 (
echo The errorlevel is less than zero
) else if errorlevel 0 (
echo The errorlevel is greater than zero
) else (
echo The errorlevel is zero
)

Resources