[SOLVED] What determines the output order from a select statement
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
What determines the output order from a select statement
What determines the order a - select opt in "${!ListOfNames[@]}" Quit - statement outputs?
The script ReadTXTFile.sh
Code:
#!/bin/bash
declare -A ListOfNames
filename="$HOME/bin/DATA/TVNames.txt"
n=1
while read line; do
# reading each line
ListOfNames[$line]=$n
n=$((n+1))
done < $filename
COLUMNS=20
PS3="Please enter your choice: "
select opt in "${!ListOfNames[@]}" Quit
do
[[ "$REPLY" =~ [^0-9] ]] && (( REPLY = $# + 1 ))
if (( REPLY <= ${#ListOfNames[*]} + 1 ))
then
break
else
echo "ERROR: Invalid choice. Must choose one of the numbers provided."
fi
done
if [[ "$opt" == Quit ]]
then
echo "quitting"
else
echo "$opt"
#
# cat <<-OUT
# =====================================
# Name of TV person is: $opt
# Prompt for filename, title, artist etc
# =====================================
# Now this will continue with the processing
# part of the script.......
# ====== Finished Okay ================
# OUT
The above code reads this list from a file:
Code:
charlie@charlie-machine:~/bin/DATA$ ls
TVNames.txt
charlie@charlie-machine:~/bin/DATA$ cat TVNames.txt
Carol Kirkwood - BBC Weather Girl
Nina Warhurst - BBC News Girl
Lorraine Kelley - ITV
Victoria Graham - BBC Spotlight
Kirstie Allsopp - Property Expert
Catherine Southon - Antiques Expert
Nicki Chapman - Wanted Down Under
Holly Willoughby - ITV
IMAGES-
charlie@charlie-machine:~/bin/DATA$ ReadTXTFile.sh
1) Holly Willoughby - ITV
2) Catherine Southon - Antiques Expert
3) IMAGES-
4) Victoria Graham - BBC Spotlight
5) Carol Kirkwood - BBC Weather Girl
6) Kirstie Allsopp - Property Expert
7) Nicki Chapman - Wanted Down Under
8) Nina Warhurst - BBC News Girl
9) Lorraine Kelley - ITV
10) Quit
Please enter your choice:
You're reading the list into a hash table (well, an "associative array", which is almost certainly implemented using a hash table), and then just printing out the hash table as-is. Hash tables have undefined ordering.
#!/bin/bash
declare -A ListOfNames
filename="$HOME/bin/DATA/TVNames.txt"
n=1
while read line; do
# reading each line
ListOfNames[$line]=$n
n=$((n+1))
done < $filename
COLUMNS=20
PS3="Please enter your choice: "
select opt in "${ListOfNames[@]}" Quit ### <================================================
do
[[ "$REPLY" =~ [^0-9] ]] && (( REPLY = $# + 1 ))
if (( REPLY <= ${#ListOfNames[*]} + 1 ))
then
break
else
echo "ERROR: Invalid choice. Must choose one of the numbers provided."
fi
done
if [[ "$opt" == Quit ]]
then
echo "quitting"
else
echo "$opt"
You're reading the list into a hash table (well, an "associative array", which is almost certainly implemented using a hash table), and then just printing out the hash table as-is. Hash tables have undefined ordering.
Ahhh, I never thought (knew) that - I'll look into it.
I don't understand why do we need associative array at all. As a minimal modification (I would do something like):
Code:
#!/bin/bash
declare -a ListOfNames # if I remember well
filename="$HOME/bin/DATA/TVNames.txt"
while read -r line; do
# reading each line
ListOfNames+=( "$line" )
done < $filename
COLUMNS=20
PS3="Please enter your choice: "
select opt in "${ListOfNames[@]}" Quit ### <================================================
do
[[ "$REPLY" =~ [^0-9] ]] && (( REPLY = $# + 1 ))
if (( REPLY <= ${#ListOfNames[*]} + 1 ))
then
break
else
echo "ERROR: Invalid choice. Must choose one of the numbers provided."
fi
done
if [[ "$opt" == Quit ]]
then
echo "quitting"
else
echo "$opt"
fi
I don't understand why do we need associative array at all. As a minimal modification (I would do something like):
Code:
#!/bin/bash
declare -a ListOfNames # if I remember well
filename="$HOME/bin/DATA/TVNames.txt"
while read -r line; do
# reading each line
ListOfNames+=( "$line" )
done < $filename
COLUMNS=20
PS3="Please enter your choice: "
select opt in "${ListOfNames[@]}" Quit ### <================================================
do
[[ "$REPLY" =~ [^0-9] ]] && (( REPLY = $# + 1 ))
if (( REPLY <= ${#ListOfNames[*]} + 1 ))
then
break
else
echo "ERROR: Invalid choice. Must choose one of the numbers provided."
fi
done
if [[ "$opt" == Quit ]]
then
echo "quitting"
else
echo "$opt"
fi
(not tested)
I don't need an associative array, it was the first bit of code I found that did what I wanted, almost, and I was trying to figure out what it was doing, your post worked just fine and I understand the differences now, ans updated my notes - many thanks much appreciated.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.