0

I'm trying to find out how (if) you can format the output of a select loop. Right now I have:

PS3=$'\nPlease make a selection: '
echo -en "\nMain Menu\n\n"
select OPT in foo bar baz
    do
        echo "You chose $OPT"
    done

and I get this output:

Main Menu

1) foo
2) bar
3) baz

Please make a selection: 

but what I'm wanting to know is how can I indent the numbers?

Main Menu

    1) foo
    2) bar
    3) baz

Please make a selection: 

Trying to avoid using echo. I can probably do it with printf, but I don't know how. I have a ton of results, so hoping to number them dynamically.

I have found that I can format the individual items like

PS3=$'\nPlease make a selection: '
echo -en "\nMain Menu\n\n"
select OPT in $'\tfoo' $'\tbar' $'\tbaz'
    do
        echo "You chose $OPT"
    done

and I get this output, but that's not really what I'm trying to do:

Main Menu

1)     foo
2)     bar
3)     baz

Please make a selection: 

Looking forward to any fresh input on this. I've googled all the things, lol.

Thanks!

misteralexander
  • 378
  • 3
  • 16

2 Answers2

1

As chepner comment out: No, select just isn't that configurable!

But you could write something like:

OPTS=(exit foo bar baz)
nopt=$((${#OPTS[@]}-1))
while :; do
    printf "Main menu:\n\n"
    paste -d\  <(printf "\t%s)\n" ${!OPTS[@]}) <(printf "%s\n" "${OPTS[@]}")
    printf "\nPlease make a selection: "
    while ! read -srn 1 char ||
        [ -z "$char" ] || [ "${char//*([0-$nopt])}" ]; do
        :
    done
    echo -e "$char\n\nYour choice: ${OPTS[$char]}\n"
    ((char)) || break
    # Doing something with "${OPTS[$char]}" ...
done

Nota: This use extglob! You may have to run shopt -s extglob before!

Main menu:

        0) exit
        1) foo
        2) bar
        3) baz

Please make a selection: 3

Your choice: baz

Main menu:

        0) exit
        1) foo
        2) bar
        3) baz

Please make a selection: 0

Your choice: exit

Further

Have a look at this three choice boolean question: How do I prompt for Yes/No/Cancel...!

F. Hauri
  • 51,421
  • 13
  • 88
  • 109
0

Yeah I don't think select can do something like that. Probably your best bet is to use printf and a for loop.

#!/bin/bash

OPTS=(foo bar baz)

for i in "${!OPTS[@]}"; do
  printf "\t%d) %s\n" $(($i+1)) "${OPTS[$i]}"
done

read -n 1 -p "Please make a selection: " printchoice

printf "\nYou chose %s\n" ${OPTS[$(($printchoice-1))]}

The above is clunky - but it works

DanielC
  • 781
  • 5
  • 12