0

folks--

I'm getting kinda stuck, here. I have a small script that will be incorporated into a larger script. This small piece is supposed to take a user input, and compare it to a list of stored variables. If the user input matches one of the listed variables, it should output the string that is that variable; or, if it matches none of the elements, then it should write the user input to a new variable.

For context, what I've done is I've defined a few variables as strings (in this case, the citation information for textbooks). As an example:

books=() buffa7="Wilson, Buffa, Lou. Physics. Pearson, 7th edition, 2009. ISBN: 0321601831" books=+("$buffa7") giancoli6="Giancoli, Douglas C. Physics: Principles with Applications. Prentice Hall, 6th edition. ISBN: 0321736990" books=+("$giancoli6") 

My understanding of this code is that it will make an array, books, and take the variables $buffa7 and $giancoli6 and append them to the list. What I'd like to do is prompt a user for input on the source: if they input buffa7 or giancoli6, then the variable $source should be redefined to be the text assigned to the respective variable. If the user input does not match these, then the variable $source should be defined to be whatever the user input.

The problem I seem to be running into is that when the user inputs the source information, if they use buffa7, bash seems to think that if the actual string buffa7 is not in its list, then it doesn't have to do anything, and thinks that buffa7 is not in the list (which is true, because $buffa7 is). Any advice on how to proceed would be much appreciated!

2
  • 1
    This can be done using name references or variable indirection, but what you should do is use associative arrays: unix.stackexchange.com/a/177589/70524
    – muru
    CommentedFeb 17, 2020 at 4:19
  • Thank you--another user said the same thing, too, and gave me a helpful example that illuminated just why/how things would work that way. Thanks, again!
    – Wayne
    CommentedFeb 17, 2020 at 21:37

1 Answer 1

2

This can be done using name references or variable indirection, but what you should do is use associative arrays. There's no need for variables for each entry, when an associative array will do for the whole lot.

declare -A books books[buffa7]="Wilson, Buffa, Lou. Physics. Pearson, 7th edition, 2009. ISBN: 0321601831" books[giancoli6]="Giancoli, Douglas C. Physics: Principles with Applications. Prentice Hall, 6th edition. ISBN: 0321736990" 

Then:

read input source=${books[$input]} # set $source to entry from array if [[ -z $source ]] # if $source is empty after that then # $input was not in array, so source=$input # set $source to $input. fi 
2
  • 1
    With bash 4.3 onwards you can test if an array element had been set with [[ -v books[$input] ]]. Otherwise you can check if it's unset with this construct [[ -n ${books[$1]} || -z ${books[$1]-x} ]].CommentedFeb 17, 2020 at 8:31
  • Got it- thanks very much! Being a new-ish to bash programming, I know just enough to know that stuff is possible, but not quite enough to know how to debug things that "should be simple" on their own. Thanks, once again!
    – Wayne
    CommentedFeb 17, 2020 at 21:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.