#!/usr/bin/ksh93 ################################################################ #### Program: wc_k93 #### #### Description: Counts lines, words and characters in an #### input stream, file or files. #### #### Author: Dana French (dfrench@mtxia.com) #### #### Date: 07/22/2004 #### ################################################################ function wc_k93 { typeset TRUE="0" typeset FALSE="1" typeset VERBOSE="${FALSE}" typeset VERYVERB="${FALSE}" typeset CNTLINES="${FALSE}" typeset CNTWORDS="${FALSE}" typeset CNTCHARS="${FALSE}" typeset DELIM="${IFS}"$'\r' typeset -R7 LCNT WCNT CCNT typeset -R7 LTOT WTOT CTOT typeset RESULT typeset TOTAL="" typeset FNAME="" typeset STDIN="${1:+${FALSE}}" STDIN="${STDIN:-${TRUE}}" while getopts ":d:lwcvV" OPTION do case "${OPTION}" in 'd') DELIM="${OPTARG}";; 'l') CNTLINES="${TRUE}";; 'w') CNTWORDS="${TRUE}";; 'c') CNTCHARS="${TRUE}";; 'v') VERBOSE="${TRUE}";; 'V') VERYVERB="${TRUE}";; '?') print "Syntax: wc [-l] [-w] [-c] [FILE]..." && exit 1 esac done shift $(( ${OPTIND} - 1 )) (( VERYVERB == TRUE )) && set -x if (( CNTLINES == FALSE && CNTWORDS == FALSE && CNTCHARS == FALSE )) then (( VERBOSE == TRUE )) && print -u 2 "No options specified, all output printed by default" CNTLINES="${TRUE}" CNTWORDS="${TRUE}" CNTCHARS="${TRUE}" fi typeset STDIN="${1:+${FALSE}}" STDIN="${STDIN:-${TRUE}}" if (( STDIN == TRUE )) then (( VERBOSE == TRUE )) && print -u 2 "Reading from standard input" TOTAL=$( wcLWC_k93 "${DELIM}" ${CNTLINES} ${CNTWORDS} ${CNTCHARS} ) LCNT="${TOTAL%%:*}" WCNT="${TOTAL//*:(*):*/\1}" CCNT="${TOTAL##*:}" unset RESULT [[ "_${LCNT}" != _*([ ]) ]] && RESULT[0]="${LCNT}" [[ "_${WCNT}" != _*([ ]) ]] && RESULT[1]="${WCNT}" [[ "_${CCNT}" != _*([ ]) ]] && RESULT[2]="${CCNT}" print -- "${RESULT[*]}" else for FNAME in "${@}" do if [[ -f "${FNAME}" ]] then (( VERBOSE == TRUE )) && print -u 2 "Reading from file \"${FNAME}\"" exec 0<"${FNAME}" TOTAL=$( wcLWC_k93 "${DELIM}" ${CNTLINES} ${CNTWORDS} ${CNTCHARS} ) LCNT="${TOTAL%%:*}" WCNT="${TOTAL//*:(*):*/\1}" CCNT="${TOTAL##*:}" unset RESULT [[ "_${LCNT}" != _*([ ]) ]] && RESULT[0]="${LCNT}" [[ "_${WCNT}" != _*([ ]) ]] && RESULT[1]="${WCNT}" [[ "_${CCNT}" != _*([ ]) ]] && RESULT[2]="${CCNT}" print -- "${RESULT[*]} ${FNAME}" exec 0<&- if (( ${#} > 1 )) then (( CNTLINES == TRUE )) && (( LTOT = LTOT + LCNT )) && (( VERBOSE == TRUE )) && print -u 2 "Subtotal Lines: ${LTOT}" (( CNTWORDS == TRUE )) && (( WTOT = WTOT + WCNT )) && (( VERBOSE == TRUE )) && print -u 2 "Subtotal Words: ${WTOT}" (( CNTCHARS == TRUE )) && (( CTOT = CTOT + CCNT )) && (( VERBOSE == TRUE )) && print -u 2 "Subtotal Chars: ${CTOT}" fi else print -u 2 "ERROR: \"${FNAME}\" does not exist or is not a regular file." fi done if (( ${#} > 1 )) then unset RESULT [[ "_${LTOT}" != _*([ ]) ]] && RESULT[0]="${LTOT}" [[ "_${WTOT}" != _*([ ]) ]] && RESULT[1]="${WTOT}" [[ "_${WTOT}" != _*([ ]) ]] && RESULT[2]="${CTOT}" print -- "${RESULT[*]} total" fi fi return 0 } ################################################################ function wcLWC_k93 { typeset TRUE="0" typeset FALSE="1" typeset DELIM="${1}" typeset CNTLINES="${2}" typeset CNTWORDS="${3}" typeset CNTCHARS="${4}" typeset LCNT WCNT CCNT typeset RESULT typeset LINE typeset ARRY while IFS="" read -r -- LINE do (( CNTLINES == TRUE )) && (( LCNT++ )) (( CNTCHARS == TRUE )) && (( CCNT = CCNT + ${#LINE} + 1 )) if (( CNTWORDS == TRUE )) then if [[ "_${LINE}" != _*([${IFS}]) ]] then LINE="${LINE//\*/\\\*}" LINE="${LINE//\?/\\\?}" IFS="${DELIM}" ARRY=( ${LINE} ) IFS=$' \t\n' (( WCNT = WCNT + ${#ARRY[*]} )) fi fi done print "${LCNT}:${WCNT}:${CCNT}" } ################################################################ wc_k93 ${*}