Obtaining Yesterday In Bash - bash

Is there an easier way to calculate yesterday in Bash? This code (used for incremental tars)
mod_time=""
if [ ! -z ${1} ]; then
if [ "${1}" = "i" ]; then
this_month=`date +%m`
this_year=`date +%y`
last_day=`date +%d`
# Subtract one from today's day, to get yesterday.
if [ "${last_day:0:1}" = "0" ]; then
if [ "${last_day:1:1}" > "1" ]; then
last_day=$[$((${last_day:1:1})) - 1]
fi
else
last_day=$[$(($last_day)) - 1]
fi
# zero pad if necessary
if [ 10 -gt $last_day ]; then
last_day="0$last_day"
fi
mod_time=" --newer-mtime $this_month/$last_day/$this_year "
fi
fi
has a couple of problems like calculating day 0, and also not doing the right thing at the end of the month. I don't want to build in leap year calculations, and am wondering if there's an easy way to do this in Bash. If not, I'll use Clojure or Python.

Perhaps I'm missing your point, but why not:
$ date -d yesterday
Wed Feb 1 11:53:12 EST 2012
(might be a GNU extension so no promises you'll have it). If you do, I'd say it's easier :).

This might help
date -d "yesterday" +%Y%m%d
return
20120202

date -d yesterday

Well for me this seems a bit shorter:
date --date "1 day ago"

Related

Comparing 2 dates in bash [duplicate]

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

Shell Script - find prior month and pass it to variable

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

Outputting if the 10 day period is finished

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

BASH looping though time

Using BASH I want to loop from a start to end date at ten-minute intervals.
I tried
begin_date="2015-01-01 00:00:00"
end_date="2015-02-20 00:00:00"
d=$begin_date
while [ "$d" != "$end_date" ]; do
echo $d
d=$(date -d "${d} + 10 min" +"%Y-%m-%d %H:%M")
done
But it didn't work. Looking at Bash:Looping thru dates
#This works
d=$(date -I -d "${d} + 1 day")
#This doesn't work
d=$(date -d "${d} + 1 day" +"%Y-%m-%d")
What am I missing in the format string?
The expression date -d "${d} + 10 min" seems not to produce a date with an offset of 10 minutes. In fact, when I run your code, I see a date counter going backwards. (Posting this diagnostic as part of your question would help others see where the problem is; you should not require others to run your code just to see what it does.)
Anyway, the sane way to do this is to convert the dates to Unix epoch, then take it from there.
for ((d=$(date -d "$begin_date" +%s); d <= $(date -d "$end_date" +%s); d += 600))
do
date -d #$d +"%F %H:%M"
done
Doing date arithmetic in the shell is probably going to be rather inefficient; converting this to e.g. Awk or Perl might be worth your time if you find it's too sluggish, or need to run it lots of times.
The example you linked to just needs to be adjusted slightly:
#!/bin/bash
## User-specified dates.
# See [GNU Coreutils: Date] for more info
# [GNU Coreutils: Date]: https://www.gnu.org/software/coreutils/manual/html_node/Combined-date-and-time-of-day-items.html#Combined-date-and-time-of-day-items
begin_date="2015-01-01T00:00"
end_date="2015-01-01T00:40"
# Run through `date` to ensure iso-8601 consistency
startdate=$(date --iso-8601='minutes' --date="${begin_date}")
enddate=$(date --iso-8601='minutes' --date="${end_date}")
# Do loop
d="$startdate"
while [ "$d" != "$enddate" ]; do
echo $d
d=$(date --iso-8601='minutes' --date="$d + 10 minutes")
done
Note that the options -I and -d are equivalent to --iso-8601 and --date respectively.

command date script shell bsh/ksh

I need help.
I made a shell script that you pass a date earlier than 3 days in YYYYMMDD format and tell me if it is correct or not.
My question is. Can i subtract the date command 3 days?
thanks.
you can test :
DATE="20120803"
date -d #$(( `date -d "$DATE" +%s` - (3*24*60*60) ))
for the fancy solution:
INPUT="20120803"
INPUT_SECONDS=$(date -d "$INPUT" +%s)
THREEDAYSAGO_SECONDS=$(date -d "3 days ago" "+%s")
if [ $INPUT_SECONDS -lt $THREEDAYSAGO_SECONDS ]; then
echo "too early :("
fi
Although you can use the date command to do this (see Guillame's excellent answer) it may be worth considering a scripting language such as Perl to do more complex stuff more efficiently.
e.g. see this SO answer, using Perl and the DateTime.pm module:
use DateTime;
my $date = DateTime->now;
$date->subtract(days => 3);
print $date->ymd;

Resources