Unix Script: Loop over all days of a month

Dear Experts,

What I want to do in a bash script, I provide the pseudo code

currentDate=script execution date

for all days in previous month (relative to currentDate)
     currentLoopDate=Date in the format: YYYY-DD-MM
end for

e.g. if I run the script now, October 25

in the loop my first date string should be 2016-01-10
in the loop my second date string should be 2016-02-10
in the loop my last date string should be 2016-31-10
mruffAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
Abhimanyu SuriConnect With a Mentor Sr Database EngineerCommented:
Here is an example, please format the output as per your requirement and update ref_days with all months

/home>cat ref_days.txt ### month|days
10|31


/home>cat loop_date.sh
#!/usr/bin/sh

var_currdate=`date "+%Y-%d-%m"`
var_currmonth=`echo ${var_currdate}|awk -F'-' '{print $3}'`
var_date=`echo ${var_currdate}|awk -F'-' '{print $2}'`

echo $var_currdate $var_currmonth ${var_date}

if [[ `grep $var_currmonth ref_days.txt|wc -l` -eq 1 ]]
then
var_loopdays=`cat ref_days.txt|awk -F'|' '{print $2}'`
var_loop1=`expr $((${var_date}-1))`

counter=1

while [[ $counter -le $var_loop1 ]]
do
var_monthstartdate_calc=`expr $((${var_date}-$counter))`
echo "day $counter `date -d "-${var_monthstartdate_calc}days"`"
counter=`expr $(($counter+1))`
done

counter=${var_date}

while [[ ${counter} -le $var_loopdays ]]
do
var_monthstartdate_calc=`expr $(($counter-${var_date}))`
echo "day ${counter} `date -d "+${var_monthstartdate_calc}days"`"
counter=`expr $(($counter+1))`
done

else
echo "invalid month"
fi

/home>. ./loop_date.sh
2016-25-10 10 25
day 1 Sat Oct  1 12:45:56 EDT 2016
day 2 Sun Oct  2 12:45:56 EDT 2016
day 3 Mon Oct  3 12:45:56 EDT 2016
day 4 Tue Oct  4 12:45:56 EDT 2016
day 5 Wed Oct  5 12:45:56 EDT 2016
day 6 Thu Oct  6 12:45:56 EDT 2016
day 7 Fri Oct  7 12:45:56 EDT 2016
day 8 Sat Oct  8 12:45:56 EDT 2016
day 9 Sun Oct  9 12:45:56 EDT 2016
day 10 Mon Oct 10 12:45:56 EDT 2016
day 11 Tue Oct 11 12:45:56 EDT 2016
day 12 Wed Oct 12 12:45:56 EDT 2016
day 13 Thu Oct 13 12:45:56 EDT 2016
day 14 Fri Oct 14 12:45:56 EDT 2016
day 15 Sat Oct 15 12:45:56 EDT 2016
day 16 Sun Oct 16 12:45:56 EDT 2016
day 17 Mon Oct 17 12:45:56 EDT 2016
day 18 Tue Oct 18 12:45:56 EDT 2016
day 19 Wed Oct 19 12:45:56 EDT 2016
day 20 Thu Oct 20 12:45:56 EDT 2016
day 21 Fri Oct 21 12:45:56 EDT 2016
day 22 Sat Oct 22 12:45:56 EDT 2016
day 23 Sun Oct 23 12:45:56 EDT 2016
day 24 Mon Oct 24 12:45:56 EDT 2016
day 25 Tue Oct 25 12:45:56 EDT 2016
day 26 Wed Oct 26 12:45:56 EDT 2016
day 27 Thu Oct 27 12:45:56 EDT 2016
day 28 Fri Oct 28 12:45:56 EDT 2016
day 29 Sat Oct 29 12:45:56 EDT 2016
day 30 Sun Oct 30 12:45:56 EDT 2016
day 31 Mon Oct 31 12:45:56 EDT 2016
0
 
Hanno P.S.Connect With a Mentor IT Consultant and Infrastructure ArchitectCommented:
which date do we have today?
date '+%Y-%m-%d'

Open in new window

The last month would be
expr `date '+%Y%m' - 1` | sed -e 's/\(....\)/\1-'

Open in new window

Now you can start with you counter variable:
day=`expr `date '+%Y%m' - 1` | sed -e 's/\(....\)/\1-'`-01

Open in new window

0
 
Hanno P.S.IT Consultant and Infrastructure ArchitectCommented:
This variable wil vae to get incremented from day to day
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
mruffAuthor Commented:
Hi Abhimanu,
thx I am running this script under AIX and getting errors: date: illegal option --d usage: date [-] [+Field Descriptors]
0
 
mruffAuthor Commented:
Dear Hanno
I am running the script at AIX
the command
day=`expr `date '+%Y%m' - 1` | sed -e 's/\(....\)/\1-'`-01
gives an error
syntax error at line 1 : '|' unexpecgted
0
 
Hanno P.S.IT Consultant and Infrastructure ArchitectCommented:
Let's do it step by step:
1. Get today's date as "a number" consisting of current year and month
date '+%Y%m' 

Open in new window

Now try to have the result stored in a variable (and display the variable's content)
day=`date '+%Y%m' `
echo $day

Open in new window

Now, decrement this by one (to get one month back):
day=`expr $day - 1'
echo $day

Open in new window

0
 
Hanno P.S.IT Consultant and Infrastructure ArchitectCommented:
The srcipt Abhimanu provided looks pretty good to me!
Have you checked if this works?
date "+%Y-%d-%m"

Open in new window

Maybe, you want to try using single instead of double quotes:
var_currdate=`date '+%Y-%d-%m'`
echo $var_currdate

Open in new window

0
 
mruffAuthor Commented:
@Hanno
Yes I've checked the script
got an error (have to man date)
errors: date: illegal option --d usage: date [-] [+Field Descriptors]
And I did not fully understand yet, how a correct number of days for a month is picked if the ref_days.txt contains all the monts|days
0
 
Hanno P.S.IT Consultant and Infrastructure ArchitectCommented:
Does this work?
date '+%Y-%d-%m'

Open in new window


If not, check you man page for date's format string options
0
 
tel2Commented:
Hi mruff,

Good to say up front what flavour of UNIX you're using, especially if it's something like AIX.

I think AIX probably doesn't ship with GNU date.

But to confirm, what output does this give you?:
date -d 'next month'

Open in new window

And this?:
date -v -1m +%Y%m%d

Open in new window


And will you be running this as root, or as another user?  (It could make a difference to my approach.  I can explain later if required.)
0
 
tel2Connect With a Mentor Commented:
Hi again nruff,

I decided on a different strategy.

Firstly, where you wrote this:
    "for all days in previous month (relative to currentDate)"
I assume you mean this:
    "for all days in current month (relative to currentDate)"
based on your example.  Right?

#!/bin/bash

currentDate=`date +'%Y-%d-%m'`
echo "currentDate = $currentDate"  # Remove this if you don't need it
yyyy=`echo $currentDate | cut -c-4`
mm=`echo $currentDate | cut -c9-`
daysInMonth=`cal | tr '\n' ' ' | awk '{print $NF}'`
day=1
while [ $day -le $daysInMonth ]
do
        currentLoopDate=`printf %d-%02d-%02d $yyyy $day $mm`
        echo $currentLoopDate    # Remove this if you don't need it
        let day=$day+1
done

Open in new window

Here's the output:
currentDate = 2016-27-10
2016-01-10
2016-02-10
2016-03-10
2016-04-10
2016-05-10
2016-06-10
2016-07-10
2016-08-10
2016-09-10
2016-10-10
2016-11-10
2016-12-10
2016-13-10
2016-14-10
2016-15-10
2016-16-10
2016-17-10
2016-18-10
2016-19-10
2016-20-10
2016-21-10
2016-22-10
2016-23-10
2016-24-10
2016-25-10
2016-26-10
2016-27-10
2016-28-10
2016-29-10
2016-30-10
2016-31-10

Is that what you want?
0
 
mruffAuthor Commented:
thank you both!
0
 
mruffAuthor Commented:
@tel2 sorry did not notice your answer until now
I've requested from moderator to select yours as best solution and provide 300 point to you
0
 
tel2Commented:
Thanks for that, mruff.

tel2
0
 
mruffAuthor Commented:
@all, I reassigned the points as Abhimuanyu posted first and most likely put most effort in his solution I've assigned him a little more point then to you tel2.
I hope the points assignment is considered fair by all of you
thank you all for your assistance, with all your help I've finished my script
0
 
tel2Commented:
Which solution are you going to use, mruff?
0
All Courses

From novice to tech pro — start learning today.