3

I want to create a map in bash where some of the map-keys may have values containing a hyphen (-)

I've tried following code

declare -a buckets
buckets["us-east-1"]="bucketname-us-east-1";

region="us-east-1"
buckets[$region]="bucketname-us-east-1"; 

# both of them throws buckets["us-east-2"]: bad array subscript

buckets["us\-east\-1"]="bucketname-us-east-1"; 
# throws syntax error: invalid arithmetic operator (error token is "\-east\-1")

Is there any other way of creating the map?

kvantour
  • 25,269
  • 4
  • 47
  • 72
himanshu219
  • 654
  • 7
  • 22
  • 3
    `-a` is for regular arrays (integer index). `-A` is for associative arrays. –  Apr 16 '19 at 14:15
  • I already tried that sorry for not being clear I was using mac os high sierra and it seems -A option works with bash v4 – himanshu219 Apr 18 '19 at 14:41
  • Possible duplicate of [Bash 4 associative arrays: error "declare: -A: invalid option"](https://stackoverflow.com/questions/6047648/bash-4-associative-arrays-error-declare-a-invalid-option) – himanshu219 Apr 18 '19 at 14:43

1 Answers1

5

As Wumpus stated in the comments, the problem is that you've declared a regular, numerically-indexed array, when you clearly wanted an associative array. In the context of a numerically-indexed array, indices are arithmetic expressions, which can result in confusing errors, or no errors when you might expect an error!

$ declare -a foo
$ foo[abc-def]=bar

This is legal, but does not assign "bar" to the index "abc-def". It assigns "bar" to the index 0, which is what abc, def and abc-def all expand to, since they are not assigned. In other words, you're subtracting 0 from 0.

$ echo "${foo[0]}"
bar

If you try to escape the dashes you get an error, like the one you saw.

$ echo $(( abc \- def ))
bash: abc \- def : syntax error: invalid arithmetic operator (error token is "\- def ")

But you can use an associative array here, instead:

$ declare -A bar
$ bar[abc-def]=xyzzy
$ echo "${bar[abc-def]}"
xyzzy

This allows you to use strings in array indices, and they do not resolve to arithmetic expressions.

Edit: bad array subscript

I didn't see the bad array subscript at first, because you only get that on the first assignment to the array.

$ unset foo
$ foo[-1]=bad
bash: foo[-1]: bad array subscript

$ foo[0]=whatevz
$ foo[-1]=bad
$ # no error!
kojiro
  • 74,557
  • 19
  • 143
  • 201
  • Brilliant ! As an aside, you may need to stress the fact that variable expansion and arithmetic operations do happen inside the array index operator even if the index is double quoted as in `"us-east-1"`. That expands to `0-0-1` had the variables `us` and `east` were not assigned yet. Since a negative index can be used only to access an element and not to write values, the op got a `bad-subscript` error. The op would have got away had it been just `"us-east"`. This is indeed a new revelation for me :-). Correct me if I am wrong. – sjsam Apr 16 '19 at 16:04