динамическое имя для ассоциативного массива в bash

Мне нужно выполнить одни и те же операции с несколькими разными ассоциативными массивами в bash. Таким образом, я хотел бы использовать функции, чтобы избежать дублирования кода. Однако у меня возникают проблемы с доступом к данным внутри функции. Вот минималистичный пример:

#!/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

Я пробовал ${$1[$2]}, ${!1[!2]} и все другие возможные комбинации, но ни одна из них не работает. Как я могу получить доступ к этим значениям с ОБА именем массива и индексом, которые являются динамическими, а не жестко закодированными? Буду признателен за любой совет здесь.


person Hanno    schedule 15.08.2018    source источник
comment
Это может помочь: замените echo ${$1[$2]} на local x="$1[@]"; echo "${!x[$2]}". См.: Как использовать переменную как часть имени массива   -  person Cyrus    schedule 15.08.2018
comment
Это печатает все значения в массиве. Я также пробовал nm=$1; echo ${!nm[$2]}, nm=$1; echo ${!nm[!2]} и nm=$1; idx=$2 echo ${!nm[!idx]}, которые больше не выдают ошибку, а возвращают пустую переменную. nm=$1; echo ${$nm[$2]} по-прежнему делает неудачную замену   -  person Hanno    schedule 15.08.2018


Ответы (3)


Имя массива и индекс вместе необходимы для расширения косвенного параметра.

echoValue () {
    # $1  array name
    # $2  array index
    t="$1[$2]"
    echo "${!t}"
}
person chepner    schedule 15.08.2018

В Bash переменные, которые объявляются вне функции, могут использоваться как глобальные переменные. Это означает, что вы можете вызывать/получать к ним доступ из функции bash без необходимости передавать переменные в качестве аргументов внутри функции.

пример:

#!/bin/bash

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

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

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

echo ${arr1[*]}

Результат:

31
31 55

Я бы посоветовал взглянуть на это Учебное пособие по переменным Bash

person ebal    schedule 15.08.2018
comment
Спасибо, но я это уже знал. Однако смысл функции заключался в том, чтобы не использовать явное имя, потому что я хочу вызвать функцию для нескольких разных ассоциативных массивов. Приведенный выше пример — это просто разбивка проблемы. - person Hanno; 15.08.2018

Другое решение

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

person user10232641    schedule 16.08.2018