#!/bin/bash show_usage() { echo echo ${0##/*}" Usage:" echo " Cut FIELDS from STRING using separator SEP" echo "${0##/} -fFIELDS -dSEP STRING" echo exit } case $1 in ""|"-h"|"--help") show_usage ;; esac # Minimum number of arguments needed by this program MINARGS=3 # count the number of arguments given COUNT=0 for ARGV in "$@" ; do (( COUNT++ )) ; done ARGC=$COUNT # [[ $DEBUG ]] && echo "ARGC=$COUNT" ##debug # check to make sure enough arguments were given if [[ $ARGC -lt $MINARGS ]] ; then [[ $DEBUG ]] && echo "Too few arguments given (Minimum:$MINARGS)" show_usage fi # Assign the variables to ARGV[?] COUNT=0 for ARGV in "$@" ; do (( COUNT++ )) ; declare ARG_${COUNT}="$ARGV" # [[ $DEBUG ]] && echo $ARG_$COUNT ##debug done # [[ $DEBUG ]] && echo "$ARG_1 $ARG_2 $ARG_3" ##debug # process_arguments # could use for ARGV_? in ARGC for WORD in "$@" ; do case $WORD in --) echo "End of arguments" ; shift ;; # --*) echo "Long option" ; shift ;; -*) true ; case $WORD in # -f=?) [[ $DEBUG ]] && echo "Short single FIELD Option using '='" # FIELDS=${WORD:3:1} FIELDS=${WORD##*=} [[ $DEBUG ]] && echo FIELDS=$FIELDS shift ;; -f=*|--fields=*) [[ $DEBUG ]] && echo "Short range FIELD Option using '='" # FIELDS=${WORD:3} FIELDS=${WORD##*=} [[ $DEBUG ]] && echo FIELDS=$FIELDS shift ;; -f?) [[ $DEBUG ]] && echo "Short single FIELD Option" #FIELDS=${WORD:2:1} FIELDS=${WORD##*f} [[ $DEBUG ]] && echo FIELDS=$FIELDS shift ;; -f) [[ $DEBUG ]] && echo "Short split FIELD Option" # if the next argument begins with a dash if [[ ${2:0:1} != "-" ]] ; then FIELDS=$2 [[ $DEBUG ]] && echo FIELDS=$FIELDS shift 2 else echo "Missing argument" exit fi ;; -f*) [[ $DEBUG ]] && echo "Short FIELD Option range" #FIELDS=${WORD:2} FIELDS=${WORD##*f} [[ $DEBUG ]] && echo FIELDS=$FIELDS shift ;; -d*) [[ $DEBUG ]] && echo "Short-short DEL Option" SEP=${WORD##*d} [[ $DEBUG ]] && echo SEP=$SEP shift ;; esac ;; esac done STRING="$@" [[ $DEBUG ]] && echo STRING="$@" ################## # UNUSED # function _length counts the characters in a string and # echo the result. Requires PARSESTRING function _length() { COUNT=0 while [[ $PARSESTRING != "" ]] ; do # get the first remaining character FC=${PARSESTRING:0:1} # cut the first character PARSESTRING="${PARSESTRING#${FC}*}" (( COUNT++ )) done echo $COUNT } # example usage #PARSESTRING=$STRING #[[ $DEBUG ]] && echo STRINGLEN=$(_length $PARSESTRING) # function _freq counts the number of matches # of PATTERN in PARSESTRING and returns FREQ function _freq() { FREQ=0 ! [[ $PATTERN ]] && PATTERN=$1 ! [[ $PARSESTRING ]] && PARSESTRING=$2 while [[ $PARSESTRING != "" ]] ; do case $PARSESTRING in *$PATTERN*) FREQ=$(( FREQ + 1 )) ; PARSESTRING=${PARSESTRING#*${PATTERN}} ;; *) PARSESTRING="" ;; esac done echo $FREQ } # example usage #PARSESTRING=$STRING #PATTERN=$SEP #[[ $DEBUG ]] && echo "Found $(_freq) matches." # _freq $SEP $STRING # _print_field is UNUSED # print the contents of a single FIELD before the SEP in PARSESTRING # Requires/defaults: FIELD=$1 PATTERN=$2 PARSESTRING=$3 function _print_field() { FREQ=0 ! [[ $FIELD ]] && FIELD=$1 ! [[ $PATTERN ]] && PATTERN=$2 ! [[ $PARSESTRING ]] && PARSESTRING=$3 while [[ $PARSESTRING != "" ]] ; do case $PARSESTRING in *$PATTERN*) FREQ=$(( FREQ + 1 )) ; # echo FIELD_${FREQ}=${PARSESTRING%%${PATTERN}*} # declare FIELD_${FREQ}=${PARSESTRING%%${PATTERN}*} # [[ $DEBUG ]] && echo "FIELD_$FREQ=$FIELD_FREQ" if [[ $FIELD = $FREQ ]] ; then # echo FIELD_${FREQ}=${PARSESTRING%%${PATTERN}*} # right_of_first SEP STUB=${PARSESTRING#*${PATTERN}} # left_of_first SEP echo ${STUB%%${PATTERN}*} fi PARSESTRING=${PARSESTRING#*${PATTERN}} #echo $PARSESTRING ;; *) PARSESTRING="" ;; esac done } # example # _print_field $FIELD $SEP $STRING _get_one_field() { if [[ $FIELD = 1 ]] ; then # output the contents to the left of the first SEP OUTPUT=${STRING%%${SEP}*} else # Chop off the first match and cheat on the count STUB=${STRING#*$SEP} COUNT=1 # skip over any matches before the requested one while [[ $COUNT -lt $(( $FIELD - 1 )) ]] ; do # ROF Chop off leading FIELD and/or SEP STUB=${STUB#*$SEP} [[ $DEBUG ]] && echo $STUB (( COUNT++ )) done # LOF Chop off trailing SEP and/or rest of STUB OUTPUT=${STUB%%${SEP}*} fi echo $OUTPUT } # examine the FIELDS variable and create a list of the chosen FIELDS # the first character is START or HEAD HEAD=${FIELDS:0:1} START=$HEAD # if the second character is a '-' then this is a range if [[ ${FIELDS:1:1} = "-" ]] ; then # if the third character is null, range goes to end of STRING if [[ ${FIELDS:2:1} = "" ]] ; then # this is an open START to END range like: 2- #echo "START to END range" START=${FIELDS:0:1} # _freq counts the number of SEP's in STRING FINISH=$(_freq $SEP $STRING) # there are always one more TOTAL_FIELDS then SEP's FINISH=$(( FINISH + 1 )) else # this is a closed range like: 2-5 #echo "closed range" START=${FIELDS:0:1} FINISH=${FIELDS:2:1} fi # translate the RANGE values to a LIST # we use a ',' comma separator but any single CHAR is okay # when the LIST gets handled we increment by 2 CHAR's LIST="$START," COUNT=$START while [[ $COUNT -lt $(( $FINISH - 1 )) ]] ; do (( COUNT++ )) LIST=$LIST$COUNT"," done LIST=$LIST$FINISH # echo LIST=$LIST elif [[ ${FIELDS:1:1} = "," ]] ; then # this is a list #echo "FIELD list" LIST=$FIELDS #echo LIST=$LIST elif [[ ${FIELDS:1:1} = "" ]] ; then # single argument given # echo "single charcter argument given" LIST=${FIELDS:0:1} fi # readfirst character of FIELDS HEAD=${LIST:0:1} # chop the first digit and comma off the LIST to increment LIST=${LIST:2} # echo the result ing HEAD #echo HEAD is: FIELD=$HEAD # set the FIELD and get the contents FIELD=$HEAD # get the contents OUTPUT="$(_get_one_field)" # echo the OUTPUT #echo FIELD=$FIELD is: $OUTPUT # start the OUTPUT_STACK with the first OUTPUT OUTPUT_STACK="$OUTPUT" ! [[ $NEW_SEP ]] && NEW_SEP=$SEP while [[ $LIST != "" ]] ; do # readfirst character FIELD=${LIST:0:1} # chop the next digit and comma off the LIST to increment LIST=${LIST:2} # the OUTPUT of the current FIELD OUTPUT="$(_get_one_field)" # add the OUTPUT to OUTPUT_STACK with a NEW_SEP between OUTPUT_STACK=$OUTPUT_STACK$NEW_SEP$OUTPUT # echo the result #echo FIELD=$FIELD is: $OUTPUT #echo " OUTPUT_STACK=$OUTPUT_STACK" done # this the final ouput FINAL_OUTPUT=$OUTPUT_STACK # echo debug # echo "FINAL_OUTPUT=$FINAL_OUTPUT" # official program FINAL_OUTPUT echo $FINAL_OUTPUT exit