#!/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 ${*}