From: Scott Bass on
Hi,

I'm writing a script (ksh) where the user enters a date parameter as
follows:

-a "begin time"

Job will not start until after begin time
begin time is in the form of month:day:hour:minute where
month 1-12, day is 1-31, hour is 0-23 and minute is 0-59.
At least 2 fields must be given hour:minute, if 3 fields
are given they are assumed to be day:hour:minute.

I would like to add error checking in the script, rather than having
the called utility choke on bad dates.

I'd like to split the user parameter into fields, then check the
fields in my script.

In Perl, the code would be something like:

($month, $day, $hour, $minute) = split(/:/, $foo);

I've also found this awk example:

foo="12:34:56"
echo $foo | awk '{split ($0, a, ":"); print a[1]}'

But I can't see how to get the array "a" into variables available to
the script.

Or perhaps another alternative is to do the entire error checking in
awk. In pseudocode:

* get date parameter from arguments
* in awk:
* split on ":" character
* check length of array - if not 2 - 4 then print error msg and exit
the script
* if two fields check hour/minute are valid else print error msg and
exit
* if three fields check day/hour/minute are valid else print error msg
and exit
* if four fields check month/day/hour/minute are valid else print
error msg and exit

1) Is the above pseudocode possible in awk?
2) And would you recommend it as a good approach?
3) If not, is there a way I can get awk to return the date parameter
split as shell variables month/day/hour/minute?

Thanks for the help and advice...

Scott
From: Chris F.A. Johnson on
On 2010-04-23, Scott Bass wrote:
> Hi,
>
> I'm writing a script (ksh) where the user enters a date parameter as
> follows:
>
> -a "begin time"
>
> Job will not start until after begin time
> begin time is in the form of month:day:hour:minute where
> month 1-12, day is 1-31, hour is 0-23 and minute is 0-59.
> At least 2 fields must be given hour:minute, if 3 fields
> are given they are assumed to be day:hour:minute.
>
> I would like to add error checking in the script, rather than having
> the called utility choke on bad dates.
>
> I'd like to split the user parameter into fields, then check the
> fields in my script.
....
> But I can't see how to get the array "a" into variables available to
> the script.

time=MM:DD:HH:MM
IFS=: read month day hour minute <<.
$time
..

--
Chris F.A. Johnson, author <http://shell.cfajohnson.com/>
===================================================================
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
===== My code in this post, if any, assumes the POSIX locale =====
===== and is released under the GNU General Public Licence =====
From: Ed Morton on
On 4/22/2010 7:30 PM, Scott Bass wrote:
> Hi,
>
> I'm writing a script (ksh) where the user enters a date parameter as
> follows:
>
> -a "begin time"
>
> Job will not start until after begin time
> begin time is in the form of month:day:hour:minute where
> month 1-12, day is 1-31, hour is 0-23 and minute is 0-59.
> At least 2 fields must be given hour:minute, if 3 fields
> are given they are assumed to be day:hour:minute.
>
> I would like to add error checking in the script, rather than having
> the called utility choke on bad dates.
>
> I'd like to split the user parameter into fields, then check the
> fields in my script.
>
> In Perl, the code would be something like:
>
> ($month, $day, $hour, $minute) = split(/:/, $foo);
>
> I've also found this awk example:
>
> foo="12:34:56"
> echo $foo | awk '{split ($0, a, ":"); print a[1]}'

Field splitting is what awk does by default. Try:

echo "$foo" | awk -F: '{print $1}'

>
> But I can't see how to get the array "a" into variables available to
> the script.

You can print var=val from awk and eval the result, but it's not pretty.

> Or perhaps another alternative is to do the entire error checking in
> awk. In pseudocode:
>
> * get date parameter from arguments
> * in awk:
> * split on ":" character

awk -F:

> * check length of array - if not 2 - 4 then print error msg and exit
> the script

(NF<2) || (NF>4) { print "error"; exit }

> * if two fields check hour/minute are valid else print error msg and
> exit

NF == 2 &&
! ( ($1 ~ /^[[:digit:]]+$/) && ($1 < 24) &&
($2 ~ /^[[:digit:]]+$/) && ($2 < 60) ) { print "error"; exit }

> * if three fields check day/hour/minute are valid else print error msg
> and exit

NF == 3 &&
! ( ($1 ~ /^[[:digit:]]+$/) && ($1 < 32) &&
($2 ~ /^[[:digit:]]+$/) && ($2 < 24) &&
($3 ~ /^[[:digit:]]+$/) && ($3 < 60) ) { print "error"; exit }

> * if four fields check month/day/hour/minute are valid else print
> error msg and exit

NF == 4 &&
! ( ($1 ~ /^[[:digit:]]+$/) && ($1 < 13) &&
($2 ~ /^[[:digit:]]+$/) && ($2 < 32) &&
($3 ~ /^[[:digit:]]+$/) && ($3 < 24) &&
($4 ~ /^[[:digit:]]+$/) && ($4 < 60) ) { print "error"; exit }

>
> 1) Is the above pseudocode possible in awk?

No :-).

> 2) And would you recommend it as a good approach?

No, it can still allow an invalid date to get through, e.g. 2/31/1/1. You could
get more specific and check for specific day maxs for specific months and leap
years if you like.

> 3) If not, is there a way I can get awk to return the date parameter
> split as shell variables month/day/hour/minute?

Yes, but that wouldn't solve the logic problem. You could instead use GNU date's
--date= argument or GNU awks' "mktime()" function to check if the specified date
is a real one by trying to use it as a date.

Ed.
>
> Thanks for the help and advice...
>
> Scott

From: Scott Bass on
On Apr 24, 2:12 am, Ed Morton <mortons...(a)gmail.com> wrote:
> On 4/23/2010 11:10 AM, Ed Morton wrote:
> <snip>
>
> > if (gotMth) {
>
>    if (gotMonth) {

Hi All,

Thanks a lot for all the help. Really really appreciated. I hope
good karma comes your way.

BTW, the called program is a batch scheduler. The end user is
specifying the date as a command line parameter to the script; it's
not the actual date. The string format is what the utility requires.
Its error message isn't great, so I'm trying to hold the user's hand.

Thanks again,
Scott
From: Ed Morton on
On 4/23/2010 9:20 PM, Scott Bass wrote:
> On Apr 24, 2:12 am, Ed Morton<mortons...(a)gmail.com> wrote:
>> On 4/23/2010 11:10 AM, Ed Morton wrote:
>> <snip>
>>
>>> if (gotMth) {
>>
>> if (gotMonth) {
>
> Hi All,
>
> Thanks a lot for all the help. Really really appreciated. I hope
> good karma comes your way.
>
> BTW, the called program is a batch scheduler. The end user is
> specifying the date as a command line parameter to the script; it's
> not the actual date.

I understood that, but you said in your first posting that "Job will not start
until after begin time" so you should check that the specified time is in the
future and to do that you need to compare with the current time.

Ed.

The string format is what the utility requires.
> Its error message isn't great, so I'm trying to hold the user's hand.
>
> Thanks again,
> Scott