Динамический bash ассоциативный массив ключей - PullRequest
1 голос
/ 05 октября 2019

Я давно борюсь с этой проблемой и, похоже, не могу найти работающего решения.

Предположим, я объявил два ассоциативных массива.

declare -A FOO_ARRAY=(
  [a]="first"
  [b]="second"
  [c]="third"
)

declare -A BAR_ARRAY=(
  [a]="first"
  [b]="second"
  [c]="third"
)

Iможно получить список ключей следующим образом:

$ echo ${!FOO_ARRAY[@]}
c b a
$ echo ${!BAR_ARRAY[@]}
c b a

Я также могу динамически извлекать ключ из массива, выполнив что-то вроде этого:

for KEY in FOO BAR
do
  temp="${KEY}_ARRAY[a]"
  echo ${!temp}
done

Однако, если вы заметите, чтоОператор для динамической ссылки на переменные также является тем же, чтобы получить список ключей из ассоциативного массива, как я мог сделать что-то подобное для того, чтобы динамически перечислять ключи в ассоциативном массиве?

Наивный пример, подобныйэто приводит к ошибке invalid variable name.

$ export NAME=foo
$ export temp="\!${NAME^^}_ARRAY[@]"
$ echo ${!temp}
bash: \!FOO_ARRAY[@]: invalid variable name

Я ищу способ динамического возврата списка ключей из ассоциативного массива, как если бы приведенный выше пример кода вернул:

c b a

Ответы [ 3 ]

3 голосов
/ 05 октября 2019

Вы можете использовать nameref:

declare -rgA FOO_ARRAY=(
  [a]="first"
  [b]="second"
  [c]="third"
)

name="foo"
declare -n array="${name^^}_ARRAY"
echo "The keys are: " "${!array[@]}"
3 голосов
/ 05 октября 2019

Используйте declare -n. От help declare:

-n  make NAME a reference to the variable named by its value

Пример:

declare -A foo_array=(
  [a]="first"
  [b]="second"
  [c]="third"
)
declare -n temp="foo_array"
echo "${!temp[@]}"  # -> a b c

Подробнее см. info bash в разделе «Bash Builtins» .

0 голосов
/ 05 октября 2019

Это будет работать

NAME=foo
temp="${NAME^^}_ARRAY[@]"
echo ${!temp}

Объяснение: здесь temp будет хранить "FOO_ARRAY [@]" только в виде строки, а когда вывести его в справочном виде, топечатает значение.

Пример

declare -rgA FOO_ARRAY=(
  [a]="first"
  [b]="second"
  [c]="third"
)

declare -rgA BAR_ARRAY=(
  [a]="first"
  [b]="second"
  [c]="third"
)

echo ${!FOO_ARRAY[@]}
echo ${!BAR_ARRAY[@]}

for KEY in FOO BAR
do
  temp="${KEY}_ARRAY[a]"
  echo ${!temp}
done

NAME=foo
temp="${NAME^^}_ARRAY[@]"
echo ${!temp}

Запуск:

a b c
a b c
first
first
first second third
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...