String generation from user input

Hi

I have one thing I need advice on, and I don't know where to start so I have no sample code.

I want the user to provide input like: 1-3,6,7,9-11

When the input is like this, I want a string to be generated including all the numbers. In the example above, the string would look like:

1 2 3 6 7 9 10 11

I guess this can be done with AWK in some way, but I have no idea how.

Does anyone have a suggestion?

Tobbe

Will it be just integers? What be the range? Does it need to be comma separated?

Hi

Yes, only integers, 1-14, and separated with space

Tobbe

Hi.

So something that would produce output like this?

% ./p1 1 2 foo 459-461
./p1: invalid number or field list: foo
1 2 459 460 461 

cheers, drl

Try...

$ n='1-3,6,7,9-11'

$ seq 1 14|paste -s|cut -f "$n"|tr '\t' ' '
1 2 3 6 7 9 10 11

$

Brilliant! I tried with awk and a pattern match on a sequence, but got nowhere.

Simplifying Ygor's inspired approach:

seq -s ' ' 14 | cut -d ' ' -f "$n"

If seq is not available, on BSD-ish systems use jot .

Regards,
Alister

Thanks a lot for that, workes great when I try it out. However, I have some troubles invoking it in my script.

I have the following:

read -p "  Blades?: " blades

blstr=seq 1 14|paste -s|cut -f "$blades"|tr '\t' ' '
hsgen="sh hostgen $blstr > hfil"
eval $hsgen

I guess I need an eval command or similar somewhere?

I'm a newbie on this. Learning, but not at the speed I had hoped...

Tobbe

First, the variable blstr is not assigned the desired result unless you use "command substitution", i.e. $(seq ... ) . Then, why do you use the hsgen variable at all instead of issuing the command itself? Third, $hsgen will execute by itself except for the redirection; if you want that, use eval $hsgen .

1 Like

Some systems (such as Solaris 10 and 11) have neither jot nor seq utilities. If you want to stay in awk rather than use jot, perl, or seq the following will work:

#!/bin/ksh
printf "%s\n" "1-3,6,7,9-11" "101-105,1000,10010-10013" | awk -F, '{
    no = 0 # number of values output for this input line
    # Loop through comma separated input fields.
    for(i = 1; i <= NF; i++) {
        n = split($i, range, "-")
        # Loop through the dash separated range.
        # Note that if there is no dash in $i, range[1] == range[n].
        for(j=range[1]; j<=range[n]; printf("%s%d", no++ ? " " : "", j++));
    }
    printf("\n")
}'

With the two lines of input I gave it, it produces the following output:

1 2 3 6 7 9 10 11
101 102 103 104 105 1000 10010 10011 10012 10013

Rudic, thanks a million.

The reason for using the hsgen part like it is, is that I need redirection to a file.

Thanks again!

Tobbe

---------- Post updated at 06:32 AM ---------- Previous update was at 06:30 AM ----------

Don Cragun, I'm on Suse Enterprise, so seq works fine. Thanks for the effort though, awk is amazingly powerful.

Tobbe

I think what RudiC was asking was: Why are you using:

hsgen="sh hostgen $blstr > hfil"
eval $hsgen

instead of: hostgen $blstr > hfil ?

bash version (space separated list, use IFS=, read ... for comma separated):

while read -p "  Blades?: " -a blades
do
  for b in "${blades[@]}"
  do
    for ((i=${b%%-*}; i<=${b##*-}; i++))
    do 
      printf "%s" "$i "
    done  
  done
  echo
done

One possible approach that's POSIX-blessed and does not use sh nor awk (for fun):

bc <<EOBC | paste -sd ' ' | cut -d ' ' -f $n
    while (x < 14) ++x
EOBC

Regards,
Alister