2012-05-15 2 views
0

Рассмотрим следующий нонсенс массив:Правильно задать массив и элемент с помощью переменных в Shell Script

# KIND[ID]=NAME 
MONKEYS[1]="Oo Oo" 
MONKEYS[2]="Aa Aa" 
MONKEYS[3]="Ba Nana" 
LIONS[5]="Mister Mufasa" 
LIONS[7]="Cocoa Puff" 
LIONS[8]="Lala Leo" 
TIGERS[13]="Ben Gal" 
TIGERS[15]="Tee Eye Double Guh Err" 
TIGERS[22]="Oh Esex Diez Punto Cuatro" 

С данной KIND и ID, я пытаюсь построить строку, которая напоминает $NAME[$ID], чтобы получить необходимый имя.

При явном указании имени массива команда ведет себя как ожидалось echo "${LIONS[5]}"=>"Mister Mufasa"). Однако всякий раз, когда используется переменная, оболочка отвечает заданным символом в строке.

$LIONS[5] => 'e' # The fifth letter in "Mister Mufasa" 

В других случаях, я не могу найти способ контролировать интерполяцию, чтобы получить NAME

KIND="LIONS" 
ID="5" 

# Attempt to return value of `LIONS` when `KIND=LIONS` 
echo $"${KIND}"; echo "\$${KIND}" #=> "$LIONS" 
echo "$${KIND}" #=> "57800{KIND}" Interpolates "$$" 
echo "\$\${KIND}"; "\$\${KIND}" #=> "$${KIND}" 

я нашел следующие работы хотя и "уродливый" ...

eval echo `echo \\$${KIND}` 

Однако при введении ID вещи снова разрываются:

eval echo `echo \\$${KIND}[$ID]` 
#> title:5: no matches found: $LIONS[5] 
#> no matches found: $LIONS[5] 

Я чувствую, что мне не хватает чего-то очень простой. У меня есть подозрение, что я забываю что-то избежать, но я не совсем уверен, что.

Кроме того, какие «менее избыточные» альтернативы eval echo `echo... или eval echo `print... существуют?

+0

возможно дубликат [Bash косвенной адресации массива?] (HTTP: // StackOverflow .com/вопросы/4582137/bash-косвенный массив-адресация) – l0b0

+0

См. [BashFAQ/006] (http://mywiki.wooledge.org/BashFAQ/006). Вероятно, вы должны использовать Bash 4 и его ассоциативные массивы или другой язык с более мощными структурами данных. –

+0

@ l0b0 На самом деле я использую более переносимую косвенную ссылку выше, так как с помощью «' \ $$ var', ... которому предшествует eval (а иногда и эхо) », является классической [косвенной ссылкой] (http: // tldp .org/ТБД/ABS/HTML/ivr.html). Синтаксис, введенный Гордоном ниже '$ {! VAR}, кажется специфичным для Bash. @Dennis, FAQ использует тот же метод. – fny

ответ

1

В Баш, использовать косвенную адресацию:

REF="$KIND[$ID]" # Sets REF to "LIONS[5]" 
echo "${!REF}" # Prints "Mister Mufasa" 

EDIT: В Zsh, используйте вложенную расширение вместо:

echo "${(P)${KIND}[ID]}" 
+0

Идеально подходит для Bash, но не больше. Последняя ZSH выполняет расширение для 'echo '$ {REF =" $ KIND [$ ID] "}" ', которое снова возвращает символ' s '. – fny

+0

Что, весь мир не использует bash? Я добавил опцию для zsh ... –

+0

Я отказался от поиска чего-то универсального. Кажется, разложения обрабатываются совсем по-разному в оболочках. – fny