Solved

Unix Script: Loop over all days of a month

Posted on 2016-10-25
17
70 Views
Last Modified: 2016-10-27
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
0
Comment
Question by:mruff
  • 6
  • 5
  • 4
  • +1
17 Comments
 
LVL 16

Assisted Solution

by:Hanno Schröder
Hanno Schröder earned 75 total points
ID: 41858882
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
 
LVL 16

Expert Comment

by:Hanno Schröder
ID: 41858883
This variable wil vae to get incremented from day to day
0
 
LVL 4

Accepted Solution

by:
Abhimanyu Suri earned 225 total points
ID: 41858968
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
 

Author Comment

by:mruff
ID: 41859811
Hi Abhimanu,
thx I am running this script under AIX and getting errors: date: illegal option --d usage: date [-] [+Field Descriptors]
0
 

Author Comment

by:mruff
ID: 41859815
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
 
LVL 16

Expert Comment

by:Hanno Schröder
ID: 41859837
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
 
LVL 16

Expert Comment

by:Hanno Schröder
ID: 41859840
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
 

Author Comment

by:mruff
ID: 41859872
@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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 16

Expert Comment

by:Hanno Schröder
ID: 41859888
Does this work?
date '+%Y-%d-%m'

Open in new window


If not, check you man page for date's format string options
0
 
LVL 11

Expert Comment

by:tel2
ID: 41859909
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
 
LVL 11

Assisted Solution

by:tel2
tel2 earned 200 total points
ID: 41860964
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
 

Author Comment

by:mruff
ID: 41862121
thank you both!
0
 

Author Comment

by:mruff
ID: 41862135
@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
 
LVL 11

Expert Comment

by:tel2
ID: 41863234
Thanks for that, mruff.

tel2
0
 

Author Comment

by:mruff
ID: 41863372
@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
 
LVL 11

Expert Comment

by:tel2
ID: 41863377
Which solution are you going to use, mruff?
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

When you do backups in the Solaris Operating System, the file system must be inactive. Otherwise, the output may be inconsistent. A file system is inactive when it's unmounted or it's write-locked by the operating system. Although the fssnap utility…
I have been running these systems for a few years now and I am just very happy with them.   I just wanted to share the manual that I have created for upgrades and other things.  Oooh yes! FreeBSD makes me happy (as a server), no maintenance and I al…
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now