0

I want to work with associative arrays in bash, and I need to be able to check whether a key is present in the array or not.

I've found this tutorial: https://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples

This is the relevant part: (Note that one has to do declare -A MYMAP first)

$ MYMAP[foo]=bar
$ echo ${MYMAP[missing]}   # Accessing a missing value gives ""

$ # Testing whether a value is missing from an associative array
$ if [ ${MYMAP[foo]+_} ]; then echo "Found"; else echo "Not found"; fi
Found
$ if [ ${MYMAP[missing]+_} ]; then echo "Found"; else echo "Not found"; fi
Not found

Never in my life have I seen the +_ in bash before, a search for "+_" bash on DDG and SO gives nothing.

What is the +_ for?

I've tried the examples with and without +_ - Both yield the same results in my testings.

confetti
  • 1,062
  • 2
  • 12
  • 27
  • The plus is the significant operator here, the underscore is just text which will be interpolated when the variable is set. So this is basically just testing whether the variable is set or not. You can easily examine this with `set -x` or by dividing it into smaller pieces, like `echo "${MYMAP[foo]+_}"` – tripleee Jan 16 '20 at 11:37
  • @tripleee Now I'm even more confused. The accepted answer in that question says "if not set, will be replaced by x" - But in the guy's examples it only prints x IF it is set. So in my example, does that mean it replaces it with `_`? If so, what does `if [ _ ]` mean, and why does what I want work with or without the `+_`? I want to know its purpose related to associative arrays, and the "duplicate" question does not even begin to answer that. – confetti Jan 16 '20 at 11:41
  • Thanks for catching that, and sorry for the confusion. I left a comment on the incorrect but accepted answer, and updated the duplicate pointer to one with a better top-voted answer (though no accepted answer). For what it's worth, `[ "$thing" ]` is true if `"$thing"` is not the empty string. – tripleee Jan 16 '20 at 11:44
  • @tripleee I see, thanks. So essentially it prevents the variable from being `""` (empty string) if it is set (but has an empty value), which would return `false`? Is that correct? I don't think an answer specifically addressing my scenario would hurt to have as I'm sure it's something more than a few people would look up. – confetti Jan 16 '20 at 11:53
  • 3
    This is much better written as `if [[ -v MYMAP[foo] ]];` since `bash` 4.2. – chepner Jan 16 '20 at 12:18
  • https://stackoverflow.com/a/19098364/874188 seems to cover exactly this scenario in the latter half of the answer. The difference between `[ "$variable" ]` and `[ "${variable+defined}" ]` is that the latter is true when `$variable` is set but empty. – tripleee Jan 16 '20 at 12:33

0 Answers0