cmd batch file check if current hour is equal to one of specific hour - datetime

I would like to develop a batch file to check the current time hour is equal to specific hour.
As long as n+2 hour (e.g. 0, 2, 4, 6, 8, 10, etc...) is matched with system current hour, it will echo to valid message, otherwise it will echo to invalid message.
Anyone can help me? Thanks.
Source Code
FOR /F %%a IN ('Powershell -Nop -c "Get-Date -Format 'HH'"') DO SET getcurrHour=%%a
FOR /L %%a IN (0,2,22) DO SET hourList=%%a
IF %getcurrHour% == %hourList% (
ECHO It's valid.
) ELSE (
ECHO It's not valid.
)

If you're using PowerShell anyhow, then let it do more of the work for you.
#%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile^
"$Hr = (Get-Date).Hour;"^
"If (((($Hr / 2) - [Math]::Truncate($Hr / 2)) * 10) -Eq 5)"^
"{ Write-Host \"It's not valid.\" }"^
"Else { Write-Host \"It's valid.\" }"
#Pause
The #Pause is included only for users testing directly from the GUI, for others it can be omitted
Just to reduce the amount of code I used to prove a point, here's a more specific example for the task you've laid out in your question, i.e. determining whether the hour is odd or even:
#powershell.exe -NoP "If (((Get-Date).Hour %% 2) -Eq 1) { Write-Host \"It's not valid.\" } Else { Write-Host \"It's valid.\" }"
#Pause
Once again the pause is only required for users invoking the batch file via the GUI.
And because inevitably, you're going to tell us that you're not really wanting to print messages to the screen, but to perform different actions based upon the odd or even result:
#For /F %%G In ('powershell.exe -NoP "(Get-Date).Hour %% 2"') Do #If %%G Equ 1 (Echo It's not valid) Else Echo It's Valid.
#Pause

FOR /F %%a IN ('Powershell -Nop -c "Get-Date -Format 'HH'"') DO SET getcurrHour=%%a
set /a "check=(1%getcurrhour%-100) %%2"
if "%check%" == "0" (
echo even hour
) else (
echo odd hour
)
I guess, the line set /a "check=(1%getcurrhour%-100) %%2 needs some explanation:
set /a also knows octal numbers. They start with a zero. 08 and 09 start with a zero, but are not valid octal numbers, so we would get a syntax error. So we precede it with a 1 and subtract 100 from that to get a valid decimal number (8) The we simply do a MOD 2 to get a zero for even numbers and a one for odd numbers.

You need to test each value in the loop, not set the last value and test.
There is another issue however. Powershell's date is returned as HH which will do:
02
etc
22
Where your for /L loop gives:
2
etc
22
Meaning for some numbers it will not be true. So we need to test if the loop is single digit or double, if single we add a leading 0
#echo off
setlocal enabledelayedexpansion
for /f %%a in ('Powershell -Nop -c "Get-Date -Format 'HH'"') do set "getcurrHour=%%a"
for /L %%a IN (0,2,22) do (
set "li=%%~a"
if "!li:~1!" == "" set "li=0!li!"
if %getcurrHour% equ !li! (
echo It's valid.
) else (
echo It's not valid.
)
)

Related

is there a way to check if a file exists with the glob * in Unix Shell Scripting?

Suppose I have the file "FILE_${RUNDATE}_0957_PROD.csv" to check if it doesn't exist, it must bypass the IF statement. If I setenv the variable $FILENAME with the full name it works with the code below, but using the '*' reg-ex ("0957" represents a timestamp which I don't know the exact value) it enters into the IF statement.
#!/bin/csh -f
set RUNDATE = `date +'%Y%m%d'`
setenv FILENAME "DATA_${RUNDATE}_*_PROD.csv"
if ( ! -eq "$FILENAME" ) then
/bin/echo "File NOT Found Locally! \n"
endif

How to create folder by Date time in batch file

I am trying to create a folder by date time in my batch file using following code
#echo off & for /F "tokens=1-4 delims=/ " %%A in ('date/t') do (
set DateDay=%%A
set DateMonth=%%B
set Date=%%C
set DateYear=%%D
)
#echo off & for /F "tokens=1-4 delims=/ " %%D in ('time/t') do (
set DateTime=%%D
)
set CurrentDate=%Date%-%DateMonth%-%DateYear%-0%time:~0,2%.%time:~3,2%.%time:~6,2%
mkdir %CurrentDate%
using this I get folder name as 22-02-2021-010.01.37
But if time Hours is in 1 to 9 hr my folder is displayed as
22-02-2021-0 9.59.19 there is always a space in 0 and 9 and 1 to 9 hr is not displayed as 01,02,03 Hr
Answer Should Be:
22-02-2021-009.59.19
The best and the correct method to get this is to use the date independently of the region day/month order, you can use "WMIC os GET LocalDateTime" as a source, since it's in ISO order:
#echo off
Title Get FileName With Date and Time
Call :GetFileNameWithDateTime MyCurrentDate
echo %MyCurrentDate%
MkDir %MyCurrentDate%
pause & exit
::----------------------------------------------------------------------------------
:GetFileNameWithDateTime <FileName>
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set "MyDate=%%x"
set "%1=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%-%MyDate:~8,2%-%MyDate:~10,2%"
Exit /B
::----------------------------------------------------------------------------------
set "CurrentDate=%Date%-%DateMonth%-%DateYear%-0%time:~0,2%.%time:~3,2%.%time:~6,2%"
set "CurrentDate=%currentDate: =0%"
mkdir %CurrentDate%
substituting 0 for in currentdate
Tips : Use set "var1=data" for setting values - this avoids problems caused by trailing spaces. In comparisons, use if "thing1" == "thing2" ... to avoid problems caused by spaces in thing1/2.
If you want something which will work on any modern system, and still output the directory name in your specific format/order, regardless of user or locale settings, then…
you could do it like this from a batch-file:
#For /F "Tokens=1-6 Delims=/: " %%G In ('%SystemRoot%\System32\Robocopy.exe \: . /NJH /L ^| %SystemRoot%\System32\find.exe " 123"') Do #MD "%%I-%%H-%%G-0%%J.%%K.%%L"
or directly from the Windows command-line, cmd.exe:
For /F "Tokens=1-6 Delims=/: " %G In ('%SystemRoot%\System32\Robocopy.exe \: . /NJH /L ^| %SystemRoot%\System32\find.exe " 123"') Do #MD %I-%H-%G-0%J.%K.%L

Compare current time to file date time last modified in Windows Batch File

I would like a command in a batch file to only execute if it has not been ran for the last 15 minutes. To achieve this I can create a "last_run" file to log the time last ran.
Where I am stuck is comparing the time last modified to the current time and taking action if the time last modified.
Here is my current code:
#echo off
set filename=last_run.txt
if not exist %filename% (
rem NOT EXISTS, CREATE FILE THEN PRINT THE LIST
echo.>"%filename%"
GOTO PrintList
) else (
rem FILE EXISTS, GET TIME LAST MODIFIED
FOR %%? IN (%filename%) DO (set filetime=%%~t?)
echo %filetime%
rem IF TIME LAST MODIFIED > 15 MINS PRINT THE LIST
if timediff??(%filetime%, current) > 15 mins {
GOTO PrintList
} else {
GOTO End
}
)
:PrintList
rem PRINT THE LIST
echo now print the list
rem WRITE TO THE FILE TO UPDATE TIME LAST MODIFIED
echo.>"%filename%"
GOTO End
:End
Another implementation using powershell from your batch-file:
#Echo Off
Set "filename=last_run.txt"
Set "minutes=15"
If Not Exist "%filename%" GoTo :PrintList
"%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile If(((Get-Date)-(Get-Item ".\%filename%").LastWriteTime).Minutes -LT %minutes%){Exit 1}
If ErrorLevel 1 Exit /B
Rem Your payload below here.
:PrintList
CD.>"%filename%"
If you are happy to accept that the PC running this code will always have the appropriate entries in %PATH% and %PATHEXT%, you can change "%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" to just PowerShell.
Besides the missing time calculation, your code has a delayed expansion problem. (My solution below doesn't need delayed expansion)
cmd is incredibly crude when it comes to date/time calculation (it can be done, but...).
Better use the help of another language (like PowerShell):
#echo off
setlocal
set "filename=last_run.txt"
set "minutes=15"
if not exist "%filename%" (
break>"%filename%"
goto :PrintList
)
for /f %%a in ('"powershell Test-Path %filename% -OlderThan (Get-Date).AddMinutes(-%minutes%)"') do set "older=%%a"
if "%older%" == "True" (
echo %filename% is older than %minutes% minutes; print list
break>"%filename%"
goto :PrintList
) else (
echo %filename% is younger than %minutes% minutes; exiting
goto :eof
)
:PrintList
echo insert your payload here.
You could use total minutes with a powerhell command.
#echo off
set error=0
if not exist last_run.txt echo File not yet existed, first run will be now & set /a error+=1
for /f "delims=," %%i in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalMinutes"') do set "now=%%i"
if "%error%" == "1" goto :run
for /f %%a in (last_run.txt) do set earlier=%%a
set /a result=%now%-%earlier%
if %result% geq 15 (
:run
echo RUN COMMANDS HERE
echo %now%>tmp.tmp
)
The concept is simple. We get the epoch time in minutes. Store the value in a file. Then compare the current minutes with the minutes in the file. if %now% is equal to or more than 15 from %earlier% the command will run. Additionally, if the file does not yet exist, it will create it and run the command first time. From there it will only run if the seconds in the file is 15 or less than current minutes.

Unix step won't complete

First, I am not a Unix scripter, but have been tasked to have the step below to check for the file size. If it is greater than 0, then it will continue to process that file.
However, if its 0, it will echo "Skip it - NO DATA IN THE dnt_pln_inconj.dat FILE"
Problem is when I run this step, it only gets as far as "Received file with data - Continue"
How can I make it continue processing if the file size is greater than 0? What am I doing wrong?
Any help would be awesome.
#Step 12: Verify pln proc inconjunction
step_num=$((step_num+1))
echo "stepnum $step_num: Verify pln proc inconjunction"
if [[ $last_step -eq $step_num ]]
then
if [[ -s ${source_dir}/${file} ]]
then
echo "Received file with data - Continue"
$scriptdir/dental_script/dnt_verify_counts.sh dnt_pln_inconj.dat PLN-130
ret_val=$?
if [[ $ret_val -ne 0 ]]
then
next_step_num=$((step_num+1))
echo $next_step_num > $logdir/$scriptname"_"step_num.log
exit $step_num
fi
else
echo "Skip it - NO DATA IN THE dnt_pln_inconj.dat FILE"
fi
last_step=$((last_step+1))
else
echo "Skip it"
fi
It all depends on what dnt_verify_counts.sh script is doing.
In your code line:
ret_val=$?
is checking for exit code of previous command - which is dnt_verify_counts.sh with parameters. I think it doesn't return file size..
If you want to check file size, play with 'du' utility for example, which gives you size of given file, e.g.:
du /path/to/dnt_pln_inconj.dat
and then, cut given data with cut, to return only size part; line:
$(du /path/to/dnt_pln_inconj.dat | cut -f 1 -)
will return given file size which you can use in your if - then - else block.conditions checking.

"set /p myvar= < file.txt" does not work - why?

I have a small Win7 dos batch and I am wondering how to do it right. Here what I do:
#echo OFF
#FOR %%D IN (*.sqlite) DO (
sqlite3 %%D "pragma integrity_check;" > %%D.check
type %%D.check
set /p CHECK= < %%D.check
del %%D.check
echo "%CHECK%"
)
I would expect that CHECK is set to the result of sqlite output. Though "type" shows the expected result, CHECK is empty!
And I do not understand what I am doing wrong.
I also tried it without using a tmpfile
FOR /F "tokens=*" %%i in ('sqlite3 %%D "pragma integrity_check;"') do SET CHECK=%%i
but this also does not work...
I'd appreciate any help/hint.
Tnx in advance,
Robert
Check is set to the correct value, but you can't see it with echo %check%, as this line is expanded while parsing the complete FOR-block, not at the execution time.
You can change to delayed expansion or a simple call :subroutine.
#echo OFF
setlocal EnableDelayedExpansion
FOR %%D IN (*.sqlite) DO (
sqlite3 %%D "pragma integrity_check;" > %%D.check
type %%D.check
set /p CHECK= < %%D.check
del %%D.check
echo "!CHECK!"
)
or
#echo OFF
FOR %%D IN (*.sqlite) DO (
sqlite3 %%D "pragma integrity_check;" > %%D.check
type %%D.check
set /p CHECK= < %%D.check
del %%D.check
call :output
)
exit /b
:output
echo "%CHECK%"
exit /b
if %%D.check contain not only one line
then the set /p=will...?

Resources