2014-09-05 4 views
2

Скажем, я начинаю только с item1=('item1' '1' '20')BASH - переменная как часть имени массива (часть 2)

тогда я определяю itemnumber=2

Я хотел бы создать следующий массив в качестве item$itemnumber=('item2' '4' '77'), но я получаю ошибка синтаксиса.

После того, что я хотел бы просто сделать itemnumber=$((itemnumber+1)) и создать item$itemnumber=('item3' '17' '15')

Что бы дать мне три массивы item1, 2 и 3:

item1=('item1' '1' '20') 
item2=('item2' '4' '77') 
item3=('item3' '17' '15') 

Возможно ли это?

+0

Какой выпуск Баш, в частности? В 4.3 и новее есть функция «namevar» (заимствованная из ksh), которая позволяет более надежную реализацию. –

ответ

3

Используйте команду declare, хотя вам нужно будет изменить способ выполнения задания.

declare -a "item$itemnumber" 
declare "item$itemnumber+=(item$itemnumber 4 77) 

bash В 4.3, это значительно упрощается с именованными ссылками.

itemnumber=0 
declare -n arr=item$itemnumber 
arr+=(item$itemnumber 1 20) 
((itemnumber++)) 
declare -n arr=item$itemnumber 
arr+=(item$itemnumber 4 77) 
((itemnumber++)) 
declare -n arr=item$itemnumber 
arr+=(item$itemnumber 17 15) 

Просто увеличивает itemnumber, сбросьте ссылку, а затем использовать ссылку, как вы бы фактический массив.

+0

Теперь, когда я получил Bash 4.3, названные ссылки работают на магию! Моя игра теперь может прогрессировать. – Alichino

5

Задачи для Eval:

itemnumber=1 
((itemnumber += 1)) 
eval "item$itemnumber=('item$itemnumber' '4' '77')" 
eval echo \${item$itemnumber[*]} 
+0

Спасибо, klashxx. Так просто: D – Alichino

1

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

#!/bin/bash 

assign() { eval "$1=($(printf '"%s" ' "[email protected]"))"; } 

itemnum=0 
assign item$((++itemnum)) 1 2 3 4 
assign item$((++itemnum)) 'q w e r' 
assign item$((++itemnum)) a "$itemnum cc" dd 

#show the array members enclosed in '' 
echo "item1:" $(printf "'%s' " "${item1[@]}") 
echo "item2:" $(printf "'%s' " "${item2[@]}") 
echo "item3:" $(printf "'%s' " "${item3[@]}") 

гравюра

item1: 'item1' '1' '2' '3' '4' 
item2: 'item2' 'q w e r' 
item3: 'item3' 'a' '3 cc' 'dd' 

или просто

echo ${item1[@]} 
echo ${item2[@]} 
echo ${item3[@]} 

печатает

item1 1 2 3 4 
item2 q w e r 
item3 a 3 cc dd 

если вы хотите исключить, то первый элемент из массива (ITEMNAME), используйте

assign() { var="$1"; shift 1; eval "$var=($(printf '"%s" ' "[email protected]"))"; } 

n=0 
assign item((++n)) 1 2 3 4 
echo "item1 contains only: $item1[@]}" 

отпечатки

item1 contains only: 1 2 3 4 
0

В Баш 4.3 namevar является идеальным инструментом:

set_item() { 
    local itemnumber=$1; shift 
    local -n array_name="item$itemnumber" 
    array_name=("[email protected]") 
} 
set_item 2 1 2 3 4 
set_item 3 2 3 4 5 

... будет иметь тот же эффект, как ...

item2=(1 2 3 4) 
item3=(2 3 4 5) 
Смежные вопросы