Hi.
Apparently this looked familiar to me because I had written one.
This script, s5, will show 3 methods for accumulating multiple arguments:
#!/usr/bin/env ksh
# @(#) s5 Demonstrate collecting arguments, splitting arguments.
# -a string can be repeated
# -b delimited string
# -c strings until end or next option
# -d delimiter character
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
# C=$HOME/bin/context && [ -f $C ] && . $C
echo
echo " Args before \"$*\""
aindex=0
cindex=0
# declare -a a # for bash
# declare -a c # for bash
err=0
del=","
while getopts a:b:c:d: opt
do
case $opt in
a) a[$aindex]=$OPTARG ; (( aindex++ )) ;;
b) b=$OPTARG ;;
# could use bash/ksh patterns in [[ ]] in place of grep
c)
db " before c loop, args #, 1, 2 = :$#:, :$1:, :$2:"
c[$cindex]=$2
shift
while [ -n "$1" ] && echo "$2" | grep -v -q '^[-+]'
do
c[$cindex]=$1 ; (( cindex++ ))
shift
db " at end loop, $# args are [$*]"
done
if [ -n "$1" ]
then
c[$cindex]=$1
fi
KEEPER=$2
set -- $2 $*
;;
d) del=$OPTARG ;;
*) (( err++ )) ;;
esac
done
if (( OPTIND-1 <= $# ))
then
shift $(( OPTIND-1 ))
fi
echo " Args after \"$*\""
[[ $err != 0 ]] && ( echo " Errors: $err, aborting." ; exit 1 )
# Continue processing.
# Display the content of the collected array: a.
if [[ ${#a} > 0 ]]
then
echo
echo " Multiply-specified arguments of option a, collected in array:"
for (( i=0 ; i<${#a[*]} ; i++ ))
do
echo " $i ${a[$i]}"
done
fi
# Continue processing.
# Display the content of the collected array: c.
if [[ ${#c} > 0 ]]
then
echo
echo " Collected sequence arguments of option c :"
for (( i=0 ; i<${#c[*]} ; i++ ))
do
echo " $i ${c[$i]}"
done
fi
# Split the delimiter-separated items.
if [ -n "$b" ]
then
echo
echo " Elements that were separated by \"$del\":"
v=( $( echo "$b" | sed "s/$del/ /g" ) )
i=0
for j in ${v[*]}
do
echo " $i $j"
(( i++ ))
done
fi
exit 0
This is a driver script, run5, that will exercise the methods:
#!/usr/bin/env ksh
# @(#) run5 Exercise script s5 to demonstrate methods.
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { : ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf
"\n" ) >&2 ; }
C=$HOME/bin/context && [ -f $C ] && . $C
# Test multiply-specified options.
pl " Multiply-specified options:"
./s5 -a alpha -a beta file1 ... filen
# Test comma-separated methods.
pl " Comma-separated methods:"
./s5 -b 3,4,5 file1 ... filen
# Showing unexpected results for -b=..."
pl " Expected anomaly for -b=...:"
./s5 -b=6,7
# Choose a different delimiter:"
pl " Select delimiter \":\" instead of \",\":"
./s5 -d ":" -b 8:9
# Command not found error when using bare \"|\":"
pl " Expect error for unprotected \"|\":"
./s5 -d | -b 10|11
# Protect \"|\" with quotes:"
pl " Better results for protected pipe symbol:"
./s5 -d "|" -b "10|11"
pl " Collect until new -option letter:"
./s5 -c able baker charlie -a first -a second
pl " Collect again until new -option letter:"
./s5 -c delta echo foxtrot -- file1 file2
pl " Collect once more until new -option letter or end:"
./s5 -c golf hotel india
exit 0
Executing run5 produces:
$ ./run5
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution : Debian 5.0.8 (lenny, workstation)
ksh 93s+
-----
Multiply-specified options:
Args before "-a alpha -a beta file1 ... filen"
Args after "file1 ... filen"
Multiply-specified arguments of option a, collected in array:
0 alpha
1 beta
-----
Comma-separated methods:
Args before "-b 3,4,5 file1 ... filen"
Args after "file1 ... filen"
Elements that were separated by ",":
0 3
1 4
2 5
-----
Expected anomaly for -b=...:
Args before "-b=6,7"
Args after ""
Elements that were separated by ",":
0 =6
1 7
-----
Select delimiter ":" instead of ",":
Args before "-d : -b 8:9"
Args after ""
Elements that were separated by ":":
0 8
1 9
-----
Expect error for unprotected "|":
./s5: -d: argument expected
./run5: line 33: -b: not found
./run5[33]: 11: not found [No such file or directory]
-----
Better results for protected pipe symbol:
Args before "-d | -b 10|11"
Args after ""
Elements that were separated by "|":
0 10
1 11
-----
Collect until new -option letter:
Args before "-c able baker charlie -a first -a second"
Args after ""
Multiply-specified arguments of option a, collected in array:
0 first
1 second
Collected sequence arguments of option c :
0 able
1 baker
2 charlie
-----
Collect again until new -option letter:
Args before "-c delta echo foxtrot -- file1 file2"
Args after "file1 file2"
Collected sequence arguments of option c :
0 delta
1 echo
2 foxtrot
-----
Collect once more until new -option letter or end:
Args before "-c golf hotel india"
Args after ""
Collected sequence arguments of option c :
0 golf
1 hotel
2 india
Best wishes ... cheers, drl
( Edit 1: correct minor typo )