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:
- Lexical - Alphabetic sort order
- Numeric - Sorts by decimal digits or floating point numbers
- Reverse - Changes sort order to decending
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 "${@}"
|