Как я могу ссылаться на существующий массив bash, используя 2-ю переменную, содержащую имя массива? - PullRequest
0 голосов
/ 01 декабря 2018

Мои самые полезные совпадения, когда я искал ответ перед публикацией:

Перебор массива в оболочке, имя которой хранится в переменной

Как использовать имя аргумента / параметра в качестве переменной в скрипте bash

Как перебрать массив с помощью косвенной ссылки?

Моя попытка с частичным успехом:

#!/bin/bash

declare -a large_furry_mammals
declare -a array_reference  
# I tried both declaring array_reference as an array and 
# not declaring it as an array.  no change in behavior.

large_furry_mammals=(horse zebra gorilla)


size=large
category=mammals

tmp="${size}_furry_${category}"
eval array_reference='$'$tmp

echo tmp=$tmp
echo array_reference[0]=${array_reference[0]}
echo array_reference[1]=${array_reference[1]}

Выход

tmp=large_furry_mammals
array_reference[0]=horse
array_reference[1]=

Ожидание

Я бы ожидал получить выходную зебру, когда повторил array_reference[1].

... но мне не хватает какой-то тонкости ...

Почему я не могу получить доступ к элементаммассива индекса за индексом 0?Это говорит о том, что array_reference на самом деле не обрабатывается как массив.

Я не собираюсь делать копию массива.Я хочу сослаться (что будет) на статический массив на основе переменной, указывающей на этот массив, т. Е. ${size}_furry_${category} -> large_furry_mammals.

Я был успешным с общей идеей, используяссылки, которые я опубликовал, но только если это не массив.Когда это массив, он падает для меня.

Приложение 5 декабря 2018

bash 4.3 в этом случае недоступно.Ответ @ benjamin работает под 4.3.

Мне нужно будет перебрать содержимое результирующей переменной массива.Этот довольно глупый пример, который я привел с участием млекопитающих, был просто для описания концепции.На самом деле вокруг этого есть реальный случай.У меня есть набор статических эталонных массивов, и входная строка будет проанализирована, чтобы выбрать, какой массив был релевантным, и затем я переберу массив, который был выбран.Я мог бы сделать оператор case, но с более чем 100 ссылочными массивами, который был бы прямым, но слишком многословным способом сделать это.

Этот псевдокод, вероятно, является лучшим примером того, что я собираюсь сделать.

m1_array=(x a r d)
m2_array=(q 3 fg d)
m3_array=(c e p)

Based on some logic...select which array prefix you need.
x=m1

for each element in ${x}_array
do
   some-task
done

Я провожу некоторые тесты с решением @ eduardo, чтобы посмотреть, смогу ли я адаптировать способ, которым он ссылается на переменные, чтобы попасть в мой финал.

** Приложение № 2 14 декабря 2018 года **

Решение

Я нашел это!Работая с примером @ eduardo, я придумал следующее:

#!/bin/bash

declare -a large_furry_mammals
#declare -a array_reference

large_furry_mammals=(horse zebra gorilla)


size=large
category=mammals

tmp="${size}_furry_${category}[@]"

for element in "${!tmp}"
do
    echo $element
done

Вот как выглядит выполнение.Мы успешно перебираем элементы строки массива, которая была построена динамически.

./example3b.sh

horse
zebra
gorilla

Спасибо всем.

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Если у вас Bash 4.3 или новее, вы можете использовать namerefs :

large_furry_mammals=(horse zebra gorilla)
size=large
category=mammals
declare -n array_reference=${size}_furry_$category
printf '%s\n' "${array_reference[@]}"

с выводом

horse
zebra
gorilla

Это ссылка, поэтому измененияотражено в large_furry_mammals и array_reference:

$ array_reference[0]='donkey'
$ large_furry_mammals[3]='llama'
$ printf '%s\n' "${array_reference[@]}"
donkey
zebra
gorilla
llama
$ printf '%s\n' "${large_furry_mammals[@]}"
donkey
zebra
gorilla
llama
0 голосов
/ 01 декабря 2018
declare -a large_furry_mammals
declare -a array_reference
large_furry_mammals=(horse zebra gorilla)

size=large
category=mammals

echo ${large_furry_mammals[@]}
tmp="${size}_furry_${category}"
array_reference=${tmp}"[1]"
eval ${array_reference}='bear'
echo tmp=$tmp
echo ${large_furry_mammals[@]}
...