Previous | Table of Contents | Next |
The knl script is the Korn shell version of the UNIX nl command. It displays line-numbered output.
#!/bin/ksh # # knl - Korn Shell line-numbering filter # A Olczak - ASP, Inc # # Initialize line number counter integer LNUM=1 # Check usage (($# == 0)) && { print "Usage: $0 file" ;exit 1 ; } # Process each file for FILE do # Make sure file exists [[ ! -f $FILE ]] && { print no $FILE; exit 1; } # Open file for reading exec 0<$FILE # Read each line, display with line number while read -r LINE do print "$LNUM: $LINE" ((LNUM+=1)) done # Reset line number counter LNUM=1 done
The kcal script implements a menu-driven calendar program. It supports addition, deletion, modification, and listing of calendar entries. It also provides the ability to find the calendar entry for the current day and list all calendar entries.
#!/bin/ksh # # kcal - Korn Shell calendar program # # Anatole Olczak - ASP, Inc # # Process errors function error { print ${1:-"unexplained error encountered"} exit ${2} } # Check arguments if (($# > 0)) then error "Usage: $0" 1 fi # Use environment variable setting or default : ${CALFILE:=$HOME/.calfile} # Create calendar file if non-existent; flag # creation error if [[ ! -f $CALFILE ]] then print "Creating default $HOME/.calfile" > $HOME/.calfile || error "$HOME/.calfile: \ cannot create" 1 fi # Variable declaration/assignment typeset DATE= LINE= ENTRY= REPLY="yes" \ PAGER=$(whence more) CLEAR=$(whence clear) # Set trap to not allow interrupts trap '$CLEAR; print "\aInterrupt ignored - use \ menu to quit. Press <Return> to continue."; \ read TMP; $CLEAR' INT QUIT # Set EXIT trap - perform cleanup trap 'rm -rf /tmp/.FOUND$$ /tmp/.CHANGE$$ \ /tmp/.DEL$$' EXIT # Check the date function checkdate { while ((1)) do # Prompt for date read DATE?"Enter date in mmdd[yy] format (default today):" case $DATE in # Default - use todays date "" ) DATE=$(date +%m-%d-%y) break ;; # Check the given date +([0-9]) ) case ${#DATE} in 4|6) # Set month to 1st 2 chars typeset -L2 MO=$DATE # Check length for year; # 4 = mmdd, 6 = mmddyy if ((${#DATE} == 6)) then # Set TMP to get date typeset -L4 TMP=$DATE # Get day typeset -R2 DA=$TMP # Get year typeset -R2 YR=$DATE else # Get day typeset -R2 DA=$DATE # Set to current year YR=$(date +%y) DATE=$DATE$YR fi # Now check values. DA # must be in range 01-31 if ((DA < 01 || DA > 31)) then print "$DA: invalid \ day format - try \ again" continue fi # Month must be 01-12 if ((MO < 01 || MO > 12)) then print "$MO: invalid \ month format - try \ again" continue fi # Set format mm-dd-yy DATE=$MO-$DA-$YR break ;; *) # Invalid format print "$DATE: invalid \ format - try again" ;; esac ;; # Invalid date given * ) print "$DATE: invalid format - try again" ;; esac done } # Add new calendar entry function addentry { $CLEAR ENTRY="$DATE" # For existent entry, just add more data COUNT=$(grep -c "^$DATE" $CALFILE) if ((COUNT > 0)) then changeentry return fi # Prompt for input print "Enter info for $DATE: (enter <Return> by itself when finished)" while ((1)) do read LINE?"=>" if [[ -n $LINE ]] then ENTRY="$ENTRY,$LINE" else break fi done # Append to calendar file print $ENTRY>>$CALFILE # Sort the calendar file sort -o $CALFILE $CALFILE } function formatentry { $CLEAR typeset IFS="," \ BORDER="*********************************" \ BORDER1="* *" \ FILE=$1 if [[ -s $FILE ]] then # Open calendar file for reading, and # format output (exec 0<$FILE while read -r ENTRY do print "$BORDER\n$BORDER1" set $ENTRY typeset -L35 LINE="DATE: $1" print "* $LINE*" shift print "$BORDER1" for i do LINE="$i" print "* $LINE*" done print "$BORDER1" done print "$BORDER" ) | $PAGER else print "No entries found." fi # Prompt to continue until [[ $REPLY = "" ]] do read REPLY?"Enter <Return> to continue..." done } # Find specific entry function findentry { $CLEAR # Check for entry - put it in temp found file grep $DATE $CALFILE >/tmp/.FOUND$$ # Format found entries formatentry /tmp/.FOUND$$ } # Change an entry function changeentry { # Find specific entry - put it in temp found file grep $DATE $CALFILE | tr ',' '\012'>/tmp/.FOUND$$ # Return if no entry was found if [[ ! -s /tmp/.FOUND$$ ]] then $CLEAR read TMP?"Entry for $DATE not found - press <Return> to continue" return fi # Prompt again for change while [[ $REPLY != "" ]] do read REPLY?"Change/Add to entry for <$DATE>?" case $REPLY in [yY]* | "" ) break ;; [nN]* ) print "Ok, aborting entry change" return ;; * ) print "Invalid reply - try again." ;; esac done # Edit the temporary found file ${EDITOR:-vi} /tmp/.FOUND$$ # Remove the specified original entry grep -v $DATE $CALFILE > /tmp/.CHANGE$$ # Put back new change in record format. # Add trailing \n (cat /tmp/.FOUND$$ | tr '\012' ',' ; print ) \ >>/tmp/.CHANGE$$ # Put back new file cat /tmp/.CHANGE$$ > $CALFILE # Clean up tmp files rm -rf /tmp/.CHANGE$$ /tmp/.FOUND$$ } # Remove specific entry function delentry { # Look for entry grep $DATE $CALFILE >/tmp/.FOUND$$ # Return if not found if [[ ! -s /tmp/.FOUND$$ ]] then $CLEAR read TMP?"Entry for $DATE not found - press <Return> to continue" return fi # Prompt to delete while [[ $REPLY != "" ]] do read REPLY?"Delete entry for <$DATE>?" case $REPLY in [yY]* | "" ) break ;; [nN]* ) print "ok, aborting delete"; return ;; * ) print "Invalid reply - try again." ;; esac done # Merge changes - put them in temporary file grep -v $DATE $CALFILE > /tmp/.DEL$$ # Put back new file cat /tmp/.DEL$$ > $CALFILE # Clean up tmp files rm -rf /tmp/.DEL$$ /tmp/.FOUND$$ } # Set menu selection prompt PS3="Enter selection or <Return> for default menu:" # Display menu while ((1)) do $CLEAR select i in "Add calendar entry" "Delete calendar entry" "Change calendar entry" "Find calendar entry" "List all calendar entries" "List todays calendar entry" "Exit" do case $i in "Add calendar entry") checkdate addentry $CLEAR ;; "Delete calendar entry") checkdate delentry $CLEAR ;; "Change calendar entry") checkdate changeentry $CLEAR ;; "Find calendar entry") checkdate findentry $CLEAR ;; "List all calendar entries") formatentry $CALFILE $CLEAR ;; "List todays calendar entry") DATE=$(date +%m-%d-%y) findentry $CLEAR ;; "Exit") exit ;; * ) print "\aInvalid selection \c" read TMP?"- press <Return> to continue" $CLEAR continue ;; esac done done
Previous | Table of Contents | Next |