This question already has answers here:
Bash script compare two date variables [duplicate]
(5 answers)
Closed 1 year ago.
So I am trying to compare 2 dates in bash , but my dates contains characters like Jan or Monday .
Can I compare them directly or do i need to format them like this "20201607"(and how do i do this plz) and them numerically compare them?
Thank you
For example:
today=$(date)
day='21 Jan 2021'
if [ $today < $day ]
echo "$day"
basically my function will just return the dates who does not happened atm.
Use the date to seconds since the epoch (1970-01-01 UTC) through specifying %s with date and so:
day='21 Jan 2021'
if [[ "$(date +%s)" -lt "$(date -d "$day" +%s)" ]];
then
echo "$day";
fi
Zenity can help you: Tell zenity what output date format you want:
while ! date=$(zenity --calendar --date-format '%Y%m%d'); do
# ...........................^^^^^^^^^^^^^^^^^^^^^^
echo "Don't cancel the zenity window, select a day"
done
# bash v4.2+ can to date formatting
today=$(printf '%(%Y%m%d)T' -1)
if [ "$date" -gt "$today" ]; then
echo "you entered a future date"
fi
Related
This question already has answers here:
Date comparison in Bash [duplicate]
(2 answers)
Closed 1 year ago.
I would like to compare line number 13 in two different files. That line contains date in the format: "Nov 8 00:46:57 2021 GMT"
I want to compare these two dates, and check which is less or greater than the other. Can someone please help me with this.
# Reads line 13 of file1.txt into date1
date1=$(awk 'NR==13' file1.txt)
# Reads line 13 of file2.txt into date2
date2=$(awk 'NR==13' file2.txt)
# converts date to seconds since the Epoch in Linux
date1=$(date -d "$date1" +%s)
date2=$(date -d "$date2" +%s)
if (( date1 >= date2 )); then
echo "Date in file1.txt is greater or equal"
else
echo "Date in file2.txt is greater"
fi
13a and 13b are your file names:
iso8601-13() {
date -d "`head -13 "$1" | tail -n 1`" --iso-8601=seconds
}
if [[ `iso8601-13 13a` < `iso8601-13 13b` ]] ; then
echo 13a is earlier
fi
I need a scipt that gets the prior month and writes it to a variable. After that I need to check if the month is a quarter month (Mar,Jun,Sep,Dec) and if it is call another script and pass the month year as an argument in the format "Sep-2020". If its not a quarter month call another script.
monthyear="Sep-2020"
if [[ quartermonth ]]
then runscript1 $monthyear
elif [[ not a quartermonth ]]
then runscript2 $monthyear
fi
bash should be available on oracle Linux; here's a bash version:
#!/bin/bash
lastmoyr=$(date '+%b-%Y' --date='1 month ago')
lm=$(date '+%m' --date='1 month ago')
lm=${lm#0}
echo last month-year "$lastmoyr"
echo last month number "$lm"
# Mar Jun Sep Dec ==> 3 6 9 12
if [[ $((lm % 3)) == 0 ]]; then
runscript1 "$lastmoyr"
else
runscript2 "$lastmoyr"
fi
You can learn how to find previous month here
$monthyear="Sep-2020" //This wont work. Refer the above link
if [[ $quartermonth % 3 -eq 0 ]] //quartermonth is the value of month taken from monthyear
then runscript1 $monthyear
elif [[ $quartermonth % 3 -ne 0]]
then runscript2 $monthyear
fi
I can't comment on the accepted answer, so'll write it as a new one.
Attention, the accepted answer will produce an unexpected result (the wrong month) in some cases, like if you run the script on 31th.
To illustrate, run this two examples on your bash shell (if your date utility doesn't support the needed options, let me know which one you're using and i'll try to adapt it).
:: From accepted answer (for simulated day 2020-October-31)
echo "Prior month? : $(date '+%b-%Y' -d "$(date -d "2020-10-31") 1 month ago")"
Prior month? : Oct-2020 - "October", probably not what you want.
versus (a more reliable solution)
echo "Prior month? : $(date '+%b-%Y' -d "$(date +%Y-%m-1 -d "2020-10-31") 1 month ago")"
Prior month? : Sep-2020 - "September" the correct prior month.
This happens because the date utility, for 'relative' calculations, for month usually uses 30 days and not "a month".
To work around this, you'll can calculate the prior month based on day 1 (or 15) instead of using the current day.
Adapting #Milag script, it would look something like.
#!/usr/bin/env bash
lastmoyr=$(date '+%b-%Y' -d "$(date +%Y-%m-1) 1 month ago")
lm=$(date '+%-m' -d "$(date +%Y-%m-1) 1 month ago")
echo last month-year "$lastmoyr"
echo last month number "$lm"
# Mar Jun Sep Dec ==> 3 6 9 12
if [[ $((lm % 3)) == 0 ]]; then
runscript1 "$lastmoyr"
else
runscript2 "$lastmoyr"
fi
I want to write a bash script that determines the 10 day period (decade) has ended relative to the start date (in the format YYYY-MM-DD).
If the 10 day period is finished script has to output the 10 days period.
Im new in bash and has a lot syntax errors with code, help me pls.
#!/bin/bash
# GNU bash, version 4.3.46
CURRENT_DATE=$(date +%Y-%m-%d)
START_DATE=2019-01-01
IS_TODAY_DECADE_CALCULATION_DAY = (CURRENT_DATE - START_DATE) % 10
if [ $IS_TODAY_DECADE_CALCULATION_DAY -eq 0 ]
then
BEGIN_DATE = $("$CURRENT_DATE - 11 days" +%Y-%m-%d)"
END_DATE = $("$CURRENT_DATE - 1 day" +%Y-%m-%d)"
echo "Period is="$BEGIN_DATE":"$END_DATE"
else
echo "Decade is not finished."
fi
You should compare the unix time stamps. If the time stamp "now+10 days" is larger than the start date, the period is ended.
#! /bin/bash
DATE_OLD=$(date "+%F" -d "-11 days")
DATE_NOW=$(date "+%F")
TEST_DATE_NOW=$(date "+%s" -d ${DATE_NOW})
TEST_DATE_OLD=$(date "+%s" -d ${DATE_OLD})
DIVIDER=$(( (TEST_DATE_NOW - TEST_DATE_OLD) / (60*60*24) ))
REMAINING=$(( DIVIDER % 10 ))
echo "Days between ${DATE_OLD} and ${DATE_NOW} is $DIVIDER"
if [ ${DIVIDER} -gt 0 ]; then
echo "Date ${DATE_OLD} is in the past"
else
echo "Date ${DATE_OLD} is in the future"
fi
if [ $REMAINING -eq 0 ]; then
echo "Ten days period ended"
else
echo "Still in ten day period"
fi
exit 0;
The question implies that the code should identify each 10 day period starting on a specific START_DATE. Bash does not have date math - it can not calculate difference between dates (as expected by '(CURRENT_DATE - START_DATE)'). Two options
Convert date to seconds since Unix Epoch, and do the math on those values, OR
Use date utilities package, OR
using Python, awk, perl
Implementing #1 is simple. Notice few changes to assignments - in particular no spaces are allowed in assignments variable=expression, or let variable=expression
#! /bin/bash
CURRENT_DATE=$(date +%Y-%m-%d)
START_DATE=2019-01-01
# Instead of IS_TODAY_DECADE_CALCULATION_DAY = (CURRENT_DATE - START_DATE) % 10
SEC_IN_DAY=$((60*60*24))
let D1=$(date '+%s' -d "$CURRENT_DATE Z")/SEC_IN_DAY
let D2=$(date '+%s' -d "$START_DATE Z")/SEC_IN_DAY
let IS_TODAY_DECADE_CALCULATION_DAY=(CURRENT_DATE-START_DATE)%10
# Rest of script here
if [ $IS_TODAY_DECADE_CALCULATION_DAY -eq 0 ]
then
BEGIN_DATE=$(date -d "$CURRENT_DATE - 11 days" +%Y-%m-%d)
END_DATE=$(date -d "$CURRENT_DATE - 1 day" +%Y-%m-%d)
echo "Period is=$BEGIN_DATE:$END_DATE"
else
echo "Decade is not finished."
fi
I am trying to create a script in which 4 days ago date should be equal to to current date if it is not then add 1 more day and check. Below is the one i have created but still not clear about answer.
#!/bin/bash
batchdate=`date --date "4 day ago" '+%Y%m%d'`
matchdate=`date --date "today" '+%Y%m%d'`
for i in {0..4}
do
if [ $batchdate != $matchdate && $NEXT_DATE != $matchdate ]; then
NEXT_DATE=$(date +%Y%m%d -d "$batchdate + $i day")
echo "$NEXT_DATE"
break
fi
done
First, define a little helper function to avoid doing the same thing in slightly different ways:
get_date () {
date +%Y-%m-%d --date "$1"
}
Now, you have two variables: the current date, which will never change, and the starting date, which you will increment one day at a time until it matches the current date.
then=$(get_date "4 days ago")
now=$(get_date "today")
while [[ $then != $now ]]; do
then=$(get_date "$then + 1 day")
echo "$then"
done
This question already has answers here:
How can I calculate time elapsed in a Bash script?
(20 answers)
Closed 5 years ago.
I'm trying to compare a date given by a user to a date in a file, basically a text file with lots of dates and times listed.
for example the user would enter a date such as 22/08/2007 and a time of 1:00, what i need the script to do is count how many dates in the text file are after the date given by the user.
I’ve managed to accomplish this by converting each date in the text file to unix timestamp and then comparing the two. Is there no way of simply comparing two dates in bash?
Thanks in advance
The GNU date command can convert a date into the number of seconds since 1970. Try this script:
#! /bin/bash
DATE=$(date -d "$3-$2-$1 01" '+%s')
COUNT=0
tr '/' ' ' | {
while read D M Y ; do
THIS=$(date -d "$Y-$M-$D 01" '+%s')
if (( THIS > DATE )) ; then
COUNT=$((COUNT + 1))
fi
done
echo $COUNT
}
It expects three arguments and the raw dates in stdin:
for D in $(seq 19 25) ; do echo $D/08/2007 ; done | ./count.sh 22 08 2007
3
It will work till 2038. ;-)
If you don't mind an external helper tool look at my dateutils. Your use case is covered by
dgrep -i '%d/%m/%Y %H:%M' '>=2007-08-22 01:00:00' < FILE | wc -l
where FILE is your file with the dates, and -i specifies the date format used in the file (I assumed dates like 22/08/2007 01:00 here). Matching lines will be printed, hence counting them gives you the information you were after.
...why don't you simply cut out the single numbers, rearrange them from the most signifcant to the less significant, put them toghether to form a new big number and then compare the other one? :) Suppose you have a date in both $1 and $2 and suppose the date format is dd-mm-yyyy (adding hours and minutes is trivial):
d1=`echo "$1" | cut -d "-" -f 1`
m1=`echo "$1" | cut -d "-" -f 2`
y1=`echo "$1" | cut -d "-" -f 3`
date1="$y1$m1$d1"
d2=`echo "$2" | cut -d "-" -f 1`
m2=`echo "$2" | cut -d "-" -f 2`
y2=`echo "$2" | cut -d "-" -f 3`
date2="$y2$m2$d2"
if [ "$date1" -gt "$date2" ]; then
#date1 > date2
else
#date2 >= date1
fi
Note that you need zeros for 1-digit fields, for example, dates like this will work:
01-01-2013
and dates like this will NOT
1-1-2013
Cheers :-)
The problem is that dates are printed in such a way that, string-wise, "1/1/2050 1:00" < "2/1/1999 0:00". And since there's no way for a script to know that something is a datetime without you saying so, you essentially have to convert any date to something that can be compared - Either you have to order the elements so that the most important (year) are first, etc. (like ISO dates) or you convert to a number.
the above command compares the date in form of integer and would work fine until you are comparing the dates of same year.
better idea is to break the dates into 3 parts of dd, mm and yyyy and then do a comparison. just as below:
sysdate=`date +%d%m%Y`
sys_dd=`echo $sysdate|cut -c1,2`
sys_mm=`echo $sysdate|cut -c3,4`
sys_yyyy=`echo $sysdate|cut -c5-8`
cd $dir_source #moving in directory where report are placed
for i in *.* #reading all the files present in directory and comparing with current sysdate
do
filename=$i
filedate=`echo $filename| cut -d '_' -f1`
file_dd=`echo $filedate|cut -c1,2`
file_mm=`echo $filedate|cut -c3,4`
file_yyyy=`echo $filedate|cut -c5-8`
if [ $sys_yyyy -lt $file_yyyy ]
then
echo "future cob file, check for the error"elif [ $sys_yyyy -gt $file_yyyy ]
then
echo "prev cob file , to be removed"
else
if [ $sys_mm -lt $file_mm ]
then
echo "future cob file, check for the error"
elif [ $sys_mm -gt $file_mm ]
then
echo "prev cob file , to be removed"
else
if [ $sys_dd -lt $file_dd ]
then
echo "future cob file, check for the error"
elif [ $sys_dd -gt $file_dd ]
then
echo "prev cob file , to be removed"
else
echo "file date is same is cob date, retaining the file as it is"
fi
fi
fi