2

I need to perform the same operations on several different associative arrays in bash. Thus, I'd like to use functions to avoid code duplication. However, I'm having troubles accessing the data inside the function. Here's a minimalistic example:

#!/bin/bash

# this function works fine
function setValue() {
    # $1  array name
    # $2  array index
    # $3  new value
    declare -g $1[$2]=$3
}

# this function doesn't
function echoValue() {
    # $1  array name
    # $2  array index
    echo ${$1[$2]}
}

declare -A arr1=( [v1]=12 [v2]=31 )
setValue arr1 v1 55
echoValue arr1 v2

I've tried ${$1[$2]}, ${!1[!2]} and all other possible combinations, but none of these work. How can I access these values with BOTH array name and index being dynamic rather than hard-coded? I'd be grateful for any advice here.

Hanno
  • 83
  • 1
  • 5
  • 1
    This might help: Replace `echo ${$1[$2]}` with `local x="$1[@]"; echo "${!x[$2]}"`. See: [How to use a variable as part of an array name](https://unix.stackexchange.com/a/60585/74329) – Cyrus Aug 15 '18 at 07:35
  • This prints all values in the array. I also tried `nm=$1; echo ${!nm[$2]}`, `nm=$1; echo ${!nm[!2]}` and `nm=$1; idx=$2 echo ${!nm[!idx]}`, which don't throw an error anymore, but returns an empty variable. `nm=$1; echo ${$nm[$2]}` still throws "bad substitution" – Hanno Aug 15 '18 at 07:56

3 Answers3

1

The array name and index together are needed for indirect parameter expansion.

echoValue () {
    # $1  array name
    # $2  array index
    t="$1[$2]"
    echo "${!t}"
}
chepner
  • 497,756
  • 71
  • 530
  • 681
0

In Bash, variables that are being declared outside of a function, can be used as Global Variables. That means you can call/access them from inside a bash function, without the need to passing variables as arguments inside the function.

an example:

#!/bin/bash

function setValue() {
  arr1[v1]=55 
}

function echoValue() {  
    echo ${arr1[v2]} 
}

declare -A arr1=( [v1]=12 [v2]=31 )  
setValue 
echoValue

echo ${arr1[*]}

The output is :

31
31 55

I would suggest to take a look on this Bash Variable Tutorial

ebal
  • 365
  • 1
  • 4
  • Thanks, but I knew that already. The point of the function, however, was to **not** use the explicit name, because I want to call the function on several different associative arrays. The example above is just a breakdown of the problem. – Hanno Aug 15 '18 at 08:02
0

Another solution

function echovalue() { local str str="echo "'$'"{$1""[$2]}" eval $str }