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!

  • 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 Feb 17 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 Feb 17 at 21:37
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
| improve this answer | |
  • 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} ]]. – roaima Feb 17 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 Feb 17 at 21:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.