Страница руководства Bash описывает использование ${!a}
для возврата содержимого переменной, имя которой является содержимым a
(уровень косвенности).
Я хотел бы знать, как вернуть все элементы в массиве, используя это, т.е.
a=(one two three)
echo ${a[*]}
возвращается
one two three
Я хотел бы для:
b=a
echo ${!b[*]}
вернуть то же самое. К сожалению, нет, но возвращается 0
.
Обновить
Учитывая ответы, я теперь понимаю, что мой пример был слишком прост, так как, конечно, что-то вроде:
b=("${a[@]}")
Достигнет именно то, что я сказал, что мне нужно.
Итак, вот что я пытался сделать:
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST=LIST_$whichone
LIST=${!_LIST[*]}
Конечно, внимательное прочтение справочной страницы Bash показывает, что это не будет работать так, как ожидалось, потому что последняя строка просто возвращает индексы «массива» $_LIST
(а не массива вообще).
В любом случае, следующее должно сделать работу (как указано):
LIST=($(eval echo \${$_LIST[*]}))
или ... (маршрут, по которому я пошел, в конце концов)
LIST_lys="lys1 lys2"
...
LIST=(${!_LIST})
Предполагая, конечно, что элементы не содержат пробелов.
[@]
к указателю,_LIST="LIST_${whichone}[@]"
а затем используйтеLIST=("${!_LIST}")
для копирования массива. Рекомендуется использовать имена переменных в нижнем регистре, чтобы избежать конфликтов с переменными среды (все заглавные буквы).Ответы:
Я думаю, что использование косвенной ссылки на переменную bash должно рассматриваться буквально.
Например. Для вашего оригинального примера:
Для последнего реального сценария, я полагаю, что код ниже будет работать.
Лучше использовать нотацию, чтобы
"${var[@]}"
избежать путаницы с$IFS
расширением и параметром. Вот окончательный код.источник
Вам нужно скопировать элементы явно. Для индексированного массива:
Для ассоциативного массива (обратите внимание, что
a
это имя переменной массива, а не переменная, значением которой является имя переменной массива):Если у вас есть имя переменной в массиве, вы можете использовать поэлементный метод с дополнительным шагом для получения ключей.
(Внимание, код в этом посте был набран прямо в браузере и не тестировался.)
источник
\${!$name[@]}
в первой строке, чтобы первое раскрытие имело только «$ name», и${!a[@]}
оно сохраняется для eval, и то же самое в цикле for с\${$name}
. Две другие обратные косые черты перед $ k также не являются строго необходимыми.${!b[*]}
расширяется до индексов, используемых в массивеb
.То , что вы хотели бы должно быть сделано в два этапа, так что
eval
поможет:eval echo \${$b[*]}
. (Обратите внимание,\
что$
первый шаг пройдет первый шаг, расширение переменной, и будет расширен только на втором шагеeval
.)Согласно Параметру Расширение
!
используется как для косвенного расширения ({!a}
), так и для Префикса соответствия имен (${!a*}
) и Списка ключей массива (${!a[*]}
). Поскольку список ключей массива имеет тот же синтаксис, что и предполагаемое косвенное расширение + расширение элемента массива, последнее не поддерживается как есть.источник
${!a}
это расширение к значению переменной , чье имя$a
. Это довольно кратко описано в руководстве, в параграфе, который начинается с «Если первым символом параметра является восклицательный знак (!
), вводится уровень переменной косвенности».${!
это довольно амбициозно, поскольку, если вы работаете с массивом, поведение будет другим.Для косвенного доступа к массивам просто добавьте
[@]
косвенную переменнуюb=a[@]
.Если эти переменные установлены:
Тогда это будет работать:
Или просто:
Такой массив можно скопировать так:
И затем напечатано с:
В одном скрипте:
Конечно, все вышеперечисленное будет копировать не разреженный массив. Тот, в котором все индексы имеют значение.
разреженные массивы
Разреженный массив - это массив, который может иметь неопределенные элементы.
Например,
a[8]=1234
определяет один элемент, а в bash от 0 до 7 не существует.Для копирования такого разреженного массива используйте этот метод
Распечатать старый массив:
Замените имя массива и захватите строку:
Проверьте строку, созданную таким образом, новый массив был определен:
источник