Solved

Bourne Shell Calendar

Posted on 2003-11-15
7
515 Views
Last Modified: 2012-06-27
Dear Experts,

I am currently taking a unix class and we were given the code below and we were asked to modify the script so it does the following:
1) chmod u+x myCal
2) ./myCal oct nov          # this would display the calendar for october and november of the the current year
3) ./myCal oct - dec        # this would display the calendar for october through december of the current year
4) ./myCal oct nov 1982  # this would display the calendar for october and november for year of 1982

QUESTION: my question to you is how do I make a iterator that counts how many fields of text were entered after executing ./myCal because I was thinking of writing a loop that until an integer(year) is entered, it sets the previous fields as the month and then it sets the integer=year.  Or maybe someone can think of a better approach?

For example:
./myCal jan mar aug sep 1982    # there are 5 fiels after the execution of myCal

Thanks a lot guys/girls,
James
The n00b @ shell programming
-----------------------------------------------------------------------------------------------------
case $# in                                        # Let the name of this file be "myCal"
0)      set `date`; m=$2; y=$6;;        # no args: use today
1)      m=$1; set `date`; y=$6;;        # 1 arg: use this year
*)      m=$1; y=$2;;
esac

case $m in
jan*|Jan*)      m=1;;
feb*|Feb*)      m=2;;
mar*|Mar*)      m=3;;
apr*|Apr*)      m=4;;
may*|May*)      m=5;;
jun*|Jun*)      m=6;;
jul*|Jul*)      m=7;;
aug*|Aug*)      m=8;;
sep*|Sep*)      m=9;;
oct*|Oct*)      m=10;;
nov*|Nov*)      m=11;;
dec*|Dec*)      m=12;;
[1-9]|10|11|12);;                        # numeric month
*)              y=$m; m="";;            # plain year
esac

/usr/bin/cal $m $y                      # run the real one
-----------------------------------------------------------------------------------------
0
Comment
Question by:Charley420
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 3

Expert Comment

by:guynumber5764
ID: 9757875
I tend to get my shells all mixed up but in bash (which is a sh derivative) you need a loop like...

for i in $* ; do
...
done

or else one using the parameter shift operator.  If you can find a directory containing a lot of scripts (like /etc/init.d) and you have a vague idea what you want, you can often use grep and view to determine the exact syntax needed.
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9757944
I think you need something like

#!/bin/bash

i=$#
echo $i
while [ $i -ne 0 ]
do
      val=$$i
      echo $val
      let i=$i-1
done

problem is $$i is not recognized by shell as such ... there was some syntax for telling the shell that there is an indirection in variables ... I had done this quite sometime ago and I can't recollect :o( ... try some advanced tutorial or reference manual

basically above loop will get you the command line parameters in the reverse order ... since year, if present, will be your last parameter, you can parse your parameters from the end ... check the last parameter against a regex like [0-9].* to determine if it is a numerical string
0
 
LVL 1

Author Comment

by:Charley420
ID: 9781060
# Unfortunately the professor specifically asked us to write everything in the bourne shell, but this is what I end up
# handing in as my assignment it works w/ the user constrain of asking them to enter in the year as oppose
# to writing the script to recognize whether the user entered in a integer or string.
# ./myCal sep - nov or ./myCal 9 - 11
# ./myCal sep oct nov
# Source: Kernighan and Pike
iterator=0
multiple=0
dash='-'
numoffield=0

echo Please enter the month you would like to see
echo If you would like to see multiple months please enter them using the syntax below
echo ./myCal jan - mar
echo The program will ask you for the year at the end

case $# in
0)      set `date`; m=$2; y=$6; numoffield=0;;  # no args: use today
1)      m=$1; set `date`; y=$6; numoffield=1;;  # 1 arg: use this year
2)      m=$1; m1=$2 numoffield=2;;
3)      m=$1; m1=$2; m2=$3; numoffield=3;;
*)      m=$1;   y=$2;;
esac

case $m in
jan*|Jan*)      m=1;;
feb*|Feb*)      m=2;;
mar*|Mar*)      m=3;;
apr*|Apr*)      m=4;;
may*|May*)      m=5;;
jun*|Jun*)      m=6;;
jul*|Jul*)      m=7;;
aug*|Aug*)      m=8;;
sep*|Sep*)      m=9;;
oct*|Oct*)      m=10;;
nov*|Nov*)      m=11;;
dec*|Dec*)      m=12;;
[1-9]|10|11|12);;
*)              m="";;
esac

case $m1 in
jan*|Jan*)      m1=1;;
feb*|Feb*)      m1=2;;
mar*|Mar*)      m1=3;;
apr*|Apr*)      m1=4;;
may*|May*)      m1=5;;
jun*|Jun*)      m1=6;;
jul*|Jul*)      m1=7;;
aug*|Aug*)      m1=8;;
sep*|Sep*)      m1=9;;
oct*|Oct*)      m1=10;;
nov*|Nov*)      m1=11;;
dec*|Dec*)      m1=12;;
[1-9]|10|11|12);;                       # numeric month
*)              y=$m1; m1="";;            # plain year
esac

case $m2 in
jan*|Jan*)      m2=1;;
feb*|Feb*)      m2=2;;
mar*|Mar*)      m2=3;;
apr*|Apr*)      m2=4;;
may*|May*)      m2=5;;
jun*|Jun*)      m2=6;;
jul*|Jul*)      m2=7;;
aug*|Aug*)      m2=8;;
sep*|Sep*)      m2=9;;
oct*|Oct*)      m2=10;;
nov*|Nov*)      m2=11;;
dec*|Dec*)      m2=12;;
[1-9]|10|11|12);;                       # numeric month
*)              y=$m2; m2="";;            # plain year
esac

echo Please enter the year that the above month are in?
read y

while [ $2 == '-' ]
do
        while [ $m -ne $m2 ]
        do
                /usr/bin/cal $m $y
                m=`expr $m + 1`
        done
        /usr/bin/cal $m2 $y
        exit
done

case $numoffield in
        0)/usr/bin/cal;;
        1)/usr/bin/cal $m $y;;
        2)/usr/bin/cal $m $y; /usr/bin/cal $m1 $y;;
        3)/usr/bin/cal $m $y; /usr/bin/cal $m1 $y;/usr/bin/cal $m2 $y;;
esac

exit 0
0
 
LVL 1

Accepted Solution

by:
cluedon earned 400 total points
ID: 10021615

you need to loop through $* and call cal for all but the last argument.   $* contains all
the command line arguments, $# contains the number of arguments.   You can get the
last argument using either awk (  echo $* | awk '{print $NF}' ) or cut (last=`echo $* | cut -d" " -f$#`).      I also moved the case check into a function to make the loop a little easier to understand, but some prof's hate global vars, even in shell scripts, so you may want to put the case check into the loop.

Try this...


#!/bin/sh

set_month()
{
  m=$1  #$0 is the first arg to the function

  #set global variable month
  case $m in
    jan*|Jan*)      month=1;;
    feb*|Feb*)      month=2;;
    mar*|Mar*)      month=3;;
    apr*|Apr*)      month=4;;
    may*|May*)      month=5;;
    jun*|Jun*)      month=6;;
    jul*|Jul*)      month=7;;
    aug*|Aug*)      month=8;;
    sep*|Sep*)      month=9;;
    oct*|Oct*)      month=10;;
    nov*|Nov*)      month=11;;
    dec*|Dec*)      month=12;;
    [1-9]|10|11|12);;                        # numeric month
    *)              y=$m; month="";;            # plain year
  esac

}

##get the number of arguments
# might use args=`echo $* | wc -w`
args=$#


##get the last argument, the year
# if you like awk use last=`echo $* | awk '{print $NF}' `
last=`echo $* | cut -d" " -f$#`
year=$last

echo "list is $* "
for arg in $*
do
  if [ $arg = $year ]
  then :    #last arg, just skip
  else
    echo processing $arg $year...
    set_month $arg
    echo /usr/bin/cal $month $year
   /usr/bin/cal $month $year                      # run the real one
  fi

done

0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
A short article about problems I had with the new location API and permissions in Marshmallow
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question