Skip to content

Fun UNIX Shell Tricks

I wanted to know what was the last date of the preceding month to now… regardless of when now is… The UNIX/Linux cal command came to the rescue:

cal -3 | cut -c1-16 | grep -v "^ *$" | tail -1 | sed -e 's/^..* \([23][0-9]\)/\1/'
It turns out you need a fairly modern version of the cal command. Darn… perhaps gnu cal will help if your system has an older cal version.

How it works…

cal -3

Gives me three months; the month prior, the month I am in, and the next month.

cut -c1-16

Ignores this month and next month.

grep -v "^ *$"

Ignores any blank lines, note the space between the ^ and the $.

tail -1

Ignores all except the last week of dates.

sed -e 's/^..* \([23][0-9]\)/\1/'

Uses the streams editor to ignore all except the last two digits, and specifically, only the last two that begin with 2 or 3 (all months have 28, 29, 30, or 31 days in them). Note the space preceding the \ character.

We are left with the last day of the preceding month, no matter which month it is now. So… why was I trying to solve this again?

Update: Alan points out that on modern systems with TimeZone features you can actually just have date itself do all the heavy lifting:
TZ=`/bin/date +%Z`
DS=`TZ=${TZ}+24 /bin/date +%m-%d-%y`
echo "Current time `/bin/date +%m-%d-%y`"
echo "One day earlier $DS"
DS=`TZ=${TZ}-24 /bin/date +%m-%d-%y`
echo "One day later $DS"

TZ=`/bin/date +%Z` ; TZ=${TZ}+24 /bin/date +%d

Post a Comment

Your email is never published nor shared. Required fields are marked *