Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Last Day of Month script - problem for OCT 4

Status
Not open for further replies.

BrianAtWork

Programmer
Apr 12, 2004
148
US
Hello All,
We use these lines in a script to get the last day of the month:
Code:
LastDayOfMonth=$(cal)
LastDayOfMonth=${LastDayOfMonth##* }
This always works well and we haven't had any problems... Until last month. For the month of october, $LastDayOfMonth is "30 31" for some reason. I tested this by typing these lines at the command prompt (KSH, by the way).
Code:
LastDayOfMonth=$(cal 10 2004)
LastDayOfMonth=${LastDayOfMonth##* }
and the LastDayOfMonth variable holds "30 31"... Why is this? These 2 lines have always worked fine, so why did October not work? Any ideas anyone?

Thanks!
 
Not sure why, but.... (I have to think about it)
Code:
LastDayOfMonth=$(echo $(cal 10 2004))
LastDayOfMonth=${LastDayOfMonth##* }

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Thanks vlad,
I looked into it, and the last day of the month in October is on a Sunday. There is an unseen newline character between the 30 and the 31 - so the ##* command is supposed to get the last block after a space - since there isn't a space between 30 31 (although it looks like it), "30 31" goes into LastDayOfMonth.

Your way works great - I looped it through 2004-2012 and it works great! Thanks so much!

Does anyone know why the extra 'echo' command gets rid of the newline?

Thanks!

Brian
 
Newbie question

Can you explain the $(LastDayOfMonth##* ) notation. It doesn't seem to work for me using ksh on AIX 5.1 ML6

Thanks

BTW I tried
Code:
echo $LastDayOfMonth
and echo seems to strip out all newlines and relace them with spaces

Columb Healy
Living with a seeker after the truth is infinitely preferable to living with one who thinks they've found it.
 
OK, now I think I understand why it didn't work withOUT the 'echo'.

The last day of Oct 2004 is Sunday which appears in the FIRST column of the 'cal 10 2004' output.

The '##*' I think implicitely works based on the value of the IFS - which by default is set to either 'space' OR 'tab'. In the case oc 'cal 10 2004' the first space/tab appears before the 30-th of the month. Therefore, the '##*' returns '30 31'.

As Columb has mentioned, doing an additional 'echo' strips all the newlines and turns them into spaces so that the output appears in one contiguous line with space separated fields. This is exatcly what the values of the IFS are set to. Therefore the '##*' works fine for the month of October 2004.

Here's the quote from 'man ksh' on 'Parameter expansion':
man ksh:
${parameter##word}
Remove Largest Prefix Pattern. The word will be
expanded to produce a pattern. The parameter
expansion then will result in parameter, with the
largest portion of the prefix matched by the pat-
tern deleted.

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
ok, NOW I really see the problem ;)

try this:
Code:
#!/bin/ksh

LastDayOfMonth="$(cal 10 2004)"
LastDayOfMonth="${LastDayOfMonth##*[!0-9]}"

As I said the problem is with the last day of the month being on Sunday - try 'cal 2 2004'.

Previously you're strpping the everything UP TO the last ' '. The 'last space' for Oct 2004 appears before the 30-th of the month. Therefore you get '30 31'.

To fix this (without the hacky 'echo') you need to specify a different pattern to '##' to strip off. Your dates are separated by anything BUT the 'number': spaces OR newLines.

Sorry about the confusin regarding the IFS - my bad ;)

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
And what about something like this ?
LastDayOfMonth=$(cal | awk '{d=$NF}END{print d}')

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Or try
LastDayOfMonth=$(echo $(cal) | awk '{print $NF}')

I hope that helps.

Mike
 
Thanks everyone - I appreciate all the tips! And thanks Vlad for enlightening me on why Feb. and Oct. would not work the way I had it.

Thanks again everyone!

Brian
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top