sortarray_k93
- Sort values from an indexed array
- Mt Xia: Technical Consulting Group

Sorts a Korn Shell indexed array of values by a variety of mechanisms:

An example of using the "sortarray" function from the command line follows:


unset ARY
ARY[0]="192.168.1.201"
ARY[1]="192.168.1.041"
ARY[2]="192.168.1.248"
ARY[3]="192.168.1.007"
ARY[4]="192.168.1.162"
ARY[5]="192.168.1.065"
ARY[6]="192.168.1.151"
ARY[7]="192.168.1.199"
ARY[8]="192.168.1.059"
ARY[9]="192.168.1.040"

. ./sortarray.ksh -a ARY

for IDX in "${!ARY[@]}"
do
  print -- "ARY[${IDX}]=${ARY[${IDX}]}"
done

ARY[0]=192.168.1.007
ARY[1]=192.168.1.040
ARY[2]=192.168.1.041
ARY[3]=192.168.1.059
ARY[4]=192.168.1.065
ARY[5]=192.168.1.151
ARY[6]=192.168.1.162
ARY[7]=192.168.1.199
ARY[8]=192.168.1.201
ARY[9]=192.168.1.248

We have expert shell programmers currently available to assist your organization with complex shell scripting projects. We have developed business continuity, disaster recovery, high availability and virtualization systems entirely in shell scripts and we have the advanced technical skills to solve your problems as well. Please Contact Us for more information.



#!/usr/bin/ksh93
################################################################
#### Copyright 2008 By Dana French, All Rights Reserved
#################################################################
function usagemsg_sortarray {
  print "
Program: sortarray

Sort of an array of values using a variety of methods

Usage: ${1##*/} [-?vV] -a ArrayName [-lrn]
  Where:
    -v = Verbose mode - displays sortarray function info
    -V = Very Verbose Mode - debug output displayed
    -a = Array Name
    -l = Lexical Sort Order (default)
    -r = Reverse Sort Order
    -n = Numeric Sort Order
    -d = Display sort results

Author: Dana French (dfrench@mtxia.com)

Copyright 2008 By Dana French, All Rights Reserved

\"AutoContent\" enabled
"
}
################################################################
#### 
#### Description:
#### 
#### Sorts an indexed array of values by a variety of mechanisms:
#### 
####   Lexical - Alphabetic sort order
####   Numeric - Sorts by decimal digits or floating point numbers
####   Reverse - Changes sort order to decending
#### 
#### Assumptions:
#### 
#### The Array is assumed to be an indexed array (not an
#### associative array).  If a numeric sort is selected, the
#### array values are assumed to be numeric values, either
#### integers or floating point values.
#### 
#### Dependencies:
#### 
#### The variable name containing the array values must be
#### specified on the command line.  This variable name
#### should not be prefixed with a dollar sign ($), only the
#### array variable name must be specified.
#### 
#### Products:
#### 
#### This script modifies the array specifed by the variable
#### name and sorts the values according to the user
#### specified options.  If no options are specified, a
#### lexical, ascending sort is performed.
#### 
#### Configured Usage:
#### 
#### This script can be run from the command line or included
#### in a library and called as a function.
#### 
#### Details:
#### 
################################################################
function sortarray {
  typeset VERSION="1.0"
  typeset TRUE="1"
  typeset FALSE="0"
  typeset EXITCODE="0"
  typeset VERBOSE="${FALSE}"
  typeset VERYVERB="${FALSE}"
  typeset LEXICAL="${TRUE}"
  typeset REVERSE="${FALSE}"
  typeset NUMERIC="${FALSE}"
  typeset DISPLAY="${FALSE}"
  typeset ARYNAME=""
  typeset ARYTEMP
  typeset IDX1
  typeset IDX2

#### 
#### Process the command line options and arguments, saving
#### the values as appropriate.
#### 

  while getopts ":vVa:lrnd" OPTION
  do
      case "${OPTION}" in
          'a') ARYNAME="${OPTARG}";;
          'r') REVERSE="${TRUE}";;
          'l') LEXICAL="${TRUE}"
               NUMERIC="${FALSE}";;
          'n') NUMERIC="${TRUE}"
               LEXICAL="${FALSE}";;
          'd') DISPLAY="${TRUE}";;
          'v') VERBOSE="${TRUE}";;
          'V') VERYVERB="${TRUE}";;
        [?:#]) usagemsg_sortarray "${0}" && return 1 ;;
      esac
  done
   
  shift $(( ${OPTIND} - 1 ))
  
  trap "usagemsg_sortarray ${0}" EXIT

  if [[ "_${ARYNAME}" == "_" ]]
  then
    print -u 2 "# ERROR: Array name not specified"
    return 2
  fi

  trap "-" EXIT
  
################################################################

#### 
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
#### 

  (( VERYVERB == TRUE )) && set -x
  (( VERBOSE  == TRUE )) && print -u 2 "# Version........: ${VERSION}"
  (( VERBOSE  == TRUE )) && print -u 2 "# True...........: ${TRUE}"
  (( VERBOSE  == TRUE )) && print -u 2 "# False  ........: ${FALSE}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Array Name.....: ${ARYNAME}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Lexical Sort...: ${LEXICAL}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Reverse Sort...: ${REVERSE}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Numeric Sort...: ${NUMERIC}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Display Results: ${DISPLAY}"

################################################################

  nameref ARYNAME="${ARYNAME}"

#
# bubble sort the Array
#
  for IDX1 in "${!ARYNAME[@]}"
  do
    (( VERBOSE  == TRUE )) && print -u 2 "# Loop 2 Element.: ${ARYNAME[${IDX1}]}"

# If numeric sort was specified, check each array value to ensure it is a number
    if (( NUMERIC == TRUE ))
    then
      if [[ "_${ARYNAME[${IDX1}]}" == _+(0) ]] ||
         [[ "_${ARYNAME[${IDX1}]}" == _+(0).*(0) ]] ||
         [[ "_${ARYNAME[${IDX1}]}" == _.+(0) ]]
      then
        (( VERBOSE  == TRUE )) && print -u 2 "# Array Value....: ${IDX1}"
      elif ! let "ARYTEMP = ${ARYNAME[${IDX1}]} + 0" > /dev/null 2>&1
      then
        (( VERBOSE  == TRUE )) && print -u 2 "# Array Value....: ${IDX1}"
        print -u 2 "#\n# ERROR..........: Non-numeric Array Value: \"${ARYNAME[${IDX1}]}\""
        return 5
      fi
    fi

    for IDX2 in "${!ARYNAME[@]}"
    do
      (( VERBOSE  == TRUE )) && print -u 2 "# Loop 2 Element.: ${ARYNAME[${IDX2}]}"

# Decending-Numeric sort
      if (( REVERSE == TRUE )) && (( NUMERIC == TRUE )) &&
         (( ${ARYNAME[${IDX1}]} > ${ARYNAME[${IDX2}]} ))
      then
        (( VERBOSE  == TRUE )) && print -u 2 "# Swapping.......: ${ARYNAME[${IDX1}]} -> ${ARYNAME[${IDX2}]}"
        ARYTEMP="${ARYNAME[${IDX2}]}"
        ARYNAME[${IDX2}]="${ARYNAME[${IDX1}]}"
        ARYNAME[${IDX1}]="${ARYTEMP}"
      fi

# Decending-Lexical sort
      if (( REVERSE == TRUE )) && (( NUMERIC == FALSE )) &&
         [[ "_${ARYNAME[${IDX1}]}" > "_${ARYNAME[${IDX2}]}" ]]
      then
        (( VERBOSE  == TRUE )) && print -u 2 "# Swapping.......: ${ARYNAME[${IDX1}]} -> ${ARYNAME[${IDX2}]}"
        ARYTEMP="${ARYNAME[${IDX2}]}"
        ARYNAME[${IDX2}]="${ARYNAME[${IDX1}]}"
        ARYNAME[${IDX1}]="${ARYTEMP}"
      fi

# Ascending-Numeric sort
      if (( REVERSE == FALSE )) && (( NUMERIC == TRUE )) &&
         (( ${ARYNAME[${IDX1}]} < ${ARYNAME[${IDX2}]} ))
      then
        (( VERBOSE  == TRUE )) && print -u 2 "# Swapping.......: ${ARYNAME[${IDX1}]} -> ${ARYNAME[${IDX2}]}"
        ARYTEMP="${ARYNAME[${IDX2}]}"
        ARYNAME[${IDX2}]="${ARYNAME[${IDX1}]}"
        ARYNAME[${IDX1}]="${ARYTEMP}"
      fi

# Ascending-Lexical sort
      if (( REVERSE == FALSE )) && (( NUMERIC == FALSE )) &&
         [[ "_${ARYNAME[${IDX1}]}" < "_${ARYNAME[${IDX2}]}" ]]
      then
        (( VERBOSE  == TRUE )) && print -u 2 "# Swapping.......: ${ARYNAME[${IDX1}]} -> ${ARYNAME[${IDX2}]}"
        ARYTEMP="${ARYNAME[${IDX2}]}"
        ARYNAME[${IDX2}]="${ARYNAME[${IDX1}]}"
        ARYNAME[${IDX1}]="${ARYTEMP}"
      fi

    done
  done

  if (( VERBOSE  == TRUE )) ||
     (( DISPLAY  == TRUE ))
  then
    for IDX1 in "${!ARY[@]}"
    do
      (( VERBOSE  == TRUE )) && print -u 2 -- "# Sort Results...: ARY[${IDX1}]=${ARY[${IDX1}]}"
      (( DISPLAY  == TRUE )) && print -- "ARY[${IDX1}]=${ARY[${IDX1}]}"
    done
  fi
  return 0
}
################################################################

sortarray "${@}"