#!/bin/bash # copyright 2007 Gilbert Ashley # minimal implementation similar to the 'wc' command VERSION=0.1 # show program usage show_usage() { echo echo ${0##/*}" Usage:" echo " Count the number of lines, words or characters in FILE" echo "${0##/} -[l|w|c] FILE" exit } show_version() { echo ${0##/*}" Version $VERSION" exit } # Minimum number of arguments needed by this program MINARGS=1 # show usage if '-h' or '--help' is the first argument or no argument is given case $1 in ""|"-h"|"--help") show_usage ;; "--version") show_version ;; esac # get the number of command-line arguments given ARGC=$# # check to make sure enough arguments were given or exit if [[ $ARGC -lt $MINARGS ]] ; then echo "Too few arguments given (Minimum:$MINARGS)" echo show_usage fi for WORD in "$@" ; do case $WORD in -*) true ; case $WORD in -m) COUNT_CHARS=1 ; shift ;; -l) COUNT_LINES=1 ; shift ;; -w) COUNT_WORDS=1 ; shift ;; --help) show_usage ;; --version) show_version ;; -*) echo "Unrecognized argument" ; show_usage ;; esac ;; esac done # function _freq counts the number of matches # of PATTERN in PARSESTRING and returns FREQ # example usage: _freq $PATTERN $PARSESTRING function _freq() { FREQ=0 ! [[ $PATTERN ]] && PATTERN=$1 ! [[ $PARSESTRING ]] && PARSESTRING=$2 while [[ $PARSESTRING != "" ]] ; do case $PARSESTRING in *$PATTERN*) (( FREQ++ )) ; PARSESTRING=${PARSESTRING#*${PATTERN}} ;; *) PARSESTRING="" ;; esac done echo $FREQ } # uniform_white() { while read GAGA ; do echo $GAGA done } # function _line_word_count counts the words in a line function _line_word_count() { LINE_WORD_COUNT=0 _freq " " $1 1> /dev/null LINE_WORD_COUNT=$(( $FREQ + 1 )) #echo "$1:$FILE_LINE_COUNT:$LINE_WORD_COUNT" #TOTAL_WORD_COUNT=$(( $TOTAL_WORD_COUNT + $LINE_WORD_COUNT )) } # function _line_char_count counts the characters in a line function _line_char_count() { LINE_CHAR_COUNT=0 PARSESTRING=$(echo $1 | uniform_white) while [[ $PARSESTRING != "" ]] ; do # read one character FC=${PARSESTRING:0:1} # advance the poiter one character PARSESTRING=${PARSESTRING:1} (( LINE_CHAR_COUNT++ )) done } if [[ $# -gt 0 ]] ; then ERROR=0 # Has there been an error (0=no, 1=yes) LINE= # Line read from file TOTAL_LINE_COUNT=0 TOTAL_WORD_COUNT=0 TOTAL_CHAR_COUNT=0 #FILE_NAME=$1 #echo "file: $1" while [ $# -gt 0 ] ; do if [ ! -r "$1" ] ; then echo "Cannot find file $1" 1>&2 exit 1 else FILE_LINE_COUNT=0 FILE_WORD_COUNT=0 FILE_CHAR_COUNT=0 IFS= while read LINE ; do # capture the text of the line STRING="$LINE" #increment the line counter (( FILE_LINE_COUNT++ )) if [[ $COUNT_WORDS ]] ; then _line_word_count $STRING TOTAL_WORD_COUNT=$(( $TOTAL_WORD_COUNT + $LINE_WORD_COUNT )) fi if [[ $COUNT_CHARS ]] ; then _line_char_count $STRING TOTAL_CHAR_COUNT=$(( $TOTAL_CHAR_COUNT + $LINE_CHAR_COUNT )) fi # then go back and read more input if needed (next LINE) done <"$1" TOTAL_LINE_COUNT=$((TOTAL_LINE_COUNT + $FILE_LINE_COUNT)) STRING="" shift fi # then go back and read more input if needed (next FILE) done shift else # this part accepts piped-in or redirected input while read FILE ; do FILE_LINE_COUNT=0 FILE_WORD_COUNT=0 FILE_CHAR_COUNT=0 IFS= while read LINE ; do # capture the text of the line STRING="$LINE" #increment the line counter (( FILE_LINE_COUNT++ )) if [[ $COUNT_WORDS ]] ; then _line_word_count $STRING TOTAL_WORD_COUNT=$(( $TOTAL_WORD_COUNT + $LINE_WORD_COUNT )) fi if [[ $COUNT_CHARS ]] ; then _line_char_count $STRING TOTAL_CHAR_COUNT=$(( $TOTAL_CHAR_COUNT + $LINE_CHAR_COUNT )) fi # then go back and read more input if needed (next LINE) shift done TOTAL_LINE_COUNT=$((TOTAL_LINE_COUNT + $FILE_LINE_COUNT)) STRING="" shift done #TOTAL_LINE_COUNT=$((TOTAL_LINE_COUNT + $FILE_LINE_COUNT)) fi if [[ $COUNT_LINES ]] ; then echo "$TOTAL_LINE_COUNT" elif [[ $COUNT_WORDS ]] ; then echo "$TOTAL_WORD_COUNT" elif [[ $COUNT_CHARS ]] ; then echo "$TOTAL_CHAR_COUNT" fi exit $ERROR