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!

1
  • 2
    No, select just isn't that configurable. Commented Dec 6, 2019 at 16:42

2 Answers 2

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...!

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.