summary: number range parsing in sh(1)

Skip Tavakkolian fst at mcgp1.UUCP
Wed Aug 3 18:56:23 AEST 1988


In article <470 at solaris.UUCP>, wyle at solaris.UUCP (Mitchell Wyle) writes:
> Here is the code now.  Anyone care to make it even
> faster?  >> grin <<   perl?  awk?   ;-)
> #!/bin/sh
> # to create a list of numbers to send such as 1,3,8-11 -> 1 3 8 9 10 11
> RA=$1
> R=""
> echo in:  $RA
> SIFS="$IFS"
> IFS=","
> for i in $RA ; do
>   R=$R" "$i
> done
> RA=$R
> IFS=$SIFS
> R=""
> for tok in $RA ; do
>   case $tok in 
>   *-*)
>     SIFS="$IFS"
>     IFS='-'
>     set $tok
>     IFS="$SIFS"
>     i=$1
>     max=${2:-99}
>     while test $i -le $max ; do
>       R=$R" "$i
>       i=`expr $i + 1`
>     done ;;
>   *)
>     R=$R" "$tok ;;
>   esac
>   RA=$R
> done
> echo out: $RA
> -- 
> -Mitchell F. Wyle            wyle at ethz.uucp

Here is an AWK script that does what you want and some time measurements
as run on a 3b2-600 SYSV 3.1.1 using time(1) (I am using the old awk).

awk '
END {
    # no error checking done here
    arg = "'$1'"
    if (length(arg) == 0)
	exit

    print "in: ", arg
    printf "out: "
    NF = split(arg, args, ",")
    for (i = 1 ; i <= NF ; i++) {
	if (split(args[i], range, "-") < 2)
	    printf "%d ", args[i]
	else {
	    for (j = range[1]; j <= range[2]; j++)
		printf "%d ", j
	    }
	}
    print
    }' </dev/null

Here are the time results:

# SHELL version
time range.sh 1,3,8-11,22,24-32
in: 1,3,8-11,22,24-32
out: 1 3 8 9 10 11 22 24 25 26 27 28 29 30 31 32

real        1.5
user        0.4
sys         0.8

# AWK version
time range.awk 1,3,8-11,22,24-32
in:  1,3,8-11,22,24-32
out: 1 3 8 9 10 11 22 24 25 26 27 28 29 30 31 32 

real        0.4
user        0.1
sys         0.1

Sincerely

-- 
Fariborz ``Skip'' Tavakkolian
UUCP	...!uw-beaver!tikal!mcgp1!fst

UNIX is a registered trademark of AT&T



More information about the Comp.unix.wizards mailing list