Getting Last Month’s Date in Bash

This one just blew me away: I spent a while trying to figure out how to turn this month's date into last month's date in a Bash script. In the script (okay, it drives AWStats reporting) I want to make a summary file for last month. To do this I want to check if a file exists with last month in it's name and if it doesn't exist I want to create it.

I started with the date command. This is a quick way to get the current date and time at the command prompt in Linux, just type "date". The date command also takes formatting parameters with an option like +%Y-m, so the command

rob@ruby:~> date +%Y-%m

Predictably answers "2006-08" for me today. To get last month's date I assumed I'd have to work with that last number, subtract one, accomodate the zero padding, yada yada yada. Yuck. Nonetheless I set to work and had a little success with turning a 08 into a 7 with expr and some backticks like expr `date +%m` - 1.

I figured I'd stuff something back into date --date="$f" with $f as my calculated date from last month. Then I started looking at the --date parameter in the man and info pages for it. All it says is
-d, --date=STRING
display time described by STRING, not `now'
So I tried "now" for STRING and sure enough it was the same as no --date parameter. Interesting. How about yesterday? Does date believe in yesterday?

rob@ruby:> date --date="yesterday" +%Y-%m-%d
2006-08-16

It sure does. So anyways, here's the one that really blew me away (and solves my problem):
rob@ruby:> date --date="last month" +%Y-%m
2006-07

Knowing that the string can be so complex I googled it just now and found this date reference (which looks like a much more detailed man page than the one in my current SuSE 10.1 install). Specifically, it says that
DATESTR can be in almost any common format. It can contain month names, timezones, 'am' and 'pm', 'yesterday', 'ago', 'next', etc.
And there are also many good examples of usage. So I guess I need a better manual installed, but then I suppose that would've spared me the joy of guessing the right answer.

0
Your rating: None

Cool. I'm actually in the process of doing the same thing for AWStats, and was googling around for a hint on how to grab the previous month from the date function. Google brought me straight here. How weird is that?

Anyway, would you be interested in sharing your script?

I've got some handy scripts for AWStats cooked up, including a souped up awstats_updateall.pl that forks off concurrent stats builds, and then a controller for that which batches things up by year... just in case we ever need to rebuild our stats... I'm ready. The forking stuff is cool, especially on a quad processor box.

The script I came up with is pretty specific to my needs, but I can share it and it can at least give you somewhere to work from. I'll send you an email and maybe I can write up an explanation to go with it here some time.

Very good find, chap. This comes in very handy for parsing out and storing log files. Much appreciated.

I was mid way through writing the \\\\\\\'yada,yada,yada\\\\\\\' part when I hit the problem of \\\\\\\'what was last month if it\\\\\\\'s January\\\\\\\'. At that point I knew there had to be a better way. Thanks for providing it!

That's fine for Linux where the gnu "date" is available, but on a bare-bones Solaris machine, the following won't work:

date --date="2 months ago" +%m

Instead, you need a more complex ksh/bash script like so:

((p=`date +%m`-2));if ((p

stupid comment limits. Here's the rest of that line:

((p=`date +%m`-2));if ((p

Nope, it was the less-than symbol. Lets try again...

((p=`date +%m`-2));if ((p<1)); then ((p+=12)); fi;echo $p

--Duane

I'm sure I rely on a lot of gnu-specific extensions and I only notice it about half the time in the man pages. Thanks for the info (even though the blog wanted to munge it).

Interesting

Thanks for the help

I'm doing a similar thing as well. I opted for python, my codes a bit hairy now, but this whole writing functional code thing is a bit new to me ;)

I'd forgotten date could handle things like 1 month ago

Thanks,
John