Solved

Bourne Shell Calendar

Posted on 2003-11-15
7
492 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
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

RIA (Rich Internet Application) tools are interactive internet applications which have many of the characteristics of desktop applications. The RIA tools typically deliver output either by the way of a site-specific browser or via browser plug-in. T…
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

747 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now