[conspire] CABAL and you: a winter's tale
Rick Moen
rick at linuxmafia.com
Tue Jan 24 00:32:52 PST 2017
Earlier this month, I wrote:
> Hey, it's about to be the second Saturday of the month on
>
> :r! cal | sed -n 4p | awk '{print $7}'
> 14
>
> ...the 14th of this very month -- thus, tomorrow.
What I posted is indeed a correct shell snippet -- but only for
Saturdays.
$ cal
January 2017
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
$
My shell snippet grabbed line four...
$ cal | sed -n 4p
8 9 10 11 12 13 14
$
...and got the seventh field.
$ cal | sed -n 4p | awk '{print $7}'
14
$
This works for Saturdays because, irrespective of what day of the week
starts a month, the first week will always include a Saturday, hence
that 1st Saturday will always be on line 3, hence the month's 2nd Saturday
will always be on the next line, line 4.
But consider 2nd Mondays. Sure, in Jan. 2017, that was on line 4, but
look at February:
$ cal February 2017
February 2017
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28
$
Because of the partial first week, the month's 2nd Monday appears on
line 5 of cal's output, not 4. So, my snippet works for Saturdays, but
not reliably for any other day of the week.
Casting about for an efficient solution, I stumbled upon ncal, which
flips cal's output:
$ ncal February 2017
February 2017
Mo 6 13 20 27
Tu 7 14 21 28
We 1 8 15 22
Th 2 9 16 23
Fr 3 10 17 24
Sa 4 11 18 25
Su 5 12 19 26
$
2nd Monday? No problem. It'll always be item 3 on ncal's 'Mo' line,
aka line 2.
$ ncal February 2017 | grep ^Mo | awk '{print $3}'
13
$
Want something even faster and lighter than awk? Use cut, though you
have to 'squeeze' space characters using tr or similar, because
otherwise cut makes dumb assumptions about what consecutive spaces mean.
$ ncal February 2017 | grep ^Mo | tr -s " " | cut -d ' ' -f 3
13
$
There, a general recipe using the fastest, lightest tools around.
More information about the conspire
mailing list