2009-12-23 2 views

ответ

965

Да есть:

ARRAY=() 
ARRAY+=('foo') 
ARRAY+=('bar') 

Bash Reference Manual :

В контексте, когда оператор присваивания присваивает значение переменной оболочки или индексу массива (см. Ar лучи), оператор '+ =' может использоваться для добавления или добавления к предыдущему значению переменной.

+11

Это прекрасно работает с Баш 3.2.48 (OS X 10.8. 2). Обратите внимание, что 'ARRAY' является просто заполнителем для фактического имени переменной. Даже если ваши индексы массива не являются последовательными, добавление с помощью '+ =' будет просто присваиваться наивысшему индексу + 1. – mklement0

+3

Есть ли что-то подобное в bash версии 4.2.24 (1)? –

+135

Важно отметить, что ARRAY + = ('foo') отличается от ARRAY + = 'foo', который добавляет строку 'foo' к записи с наименьшим (?) Ключом. – TheConstructor

13

Если ваш массив всегда последовательно и начинается с 0, то вы можете сделать это:

array[${#array[@]}] = 'foo'

${#array_name[@]} получает длину массива

+3

Да, вы можете, но синтаксис '+ =' (см. Ответ @ e-t172) является (a) более простым, и (b) также работает с массивами, которые являются несмежными и/или не начинаются с 0. – mklement0

+0

Честно говоря, это решение (для меня) работает лучше, чем «+ =», потому что с последним длина иногда ошибочна (увеличивается на два при добавлении одного элемента) ... поэтому я предпочитаю этот ответ! :) –

29
$ declare -a arr 
$ arr=("a") 
$ arr=("${arr[@]}" "new") 
$ echo ${arr[@]} 
a new 
$ arr=("${arr[@]}" "newest") 
$ echo ${arr[@]} 
a new newest 
+3

приятный для версий bash, которые не поддерживают семантику оператора + =, объясненного e-t172 – akostadinov

+7

хорошим решением, совместимым с обратной совместимостью, но будьте осторожны, если в любом из существующих элементов есть пробелы в них, они будут разделены на несколько элементы; используйте 'arr = (" $ {arr [@]} "" new ")', если у вас есть элементы с пробелами в них – kbolino

+0

Это также можно использовать для ввода перед массивом, что является именно тем, что мне нужно. –

51

Как Тупой Guy указывает, важно отметить, начинается ли массив с нуля и является последовательным. Поскольку вы можете назначать и удалять несмежные индексы, ${#array[@]} не всегда является следующим элементом в конце массива.

$ array=(a b c d e f g h) 
$ array[42]="i" 
$ unset array[2] 
$ unset array[3] 
$ declare -p array  # dump the array so we can see what it contains 
declare -a array='([0]="a" [1]="b" [4]="e" [5]="f" [6]="g" [7]="h" [42]="i")' 
$ echo ${#array[@]} 
7 
$ echo ${array[${#array[@]}]} 
h 

Вот как получить последний индекс:

$ end=(${!array[@]}) # put all the indices in an array 
$ end=${end[@]: -1} # get the last one 
$ echo $end 
42 

Это показывает, как получить последний элемент массива. Вы часто будете видеть это:

$ echo ${array[${#array[@]} - 1]} 
g 

Как вы можете видеть, потому что мы имеем дело с редким массивом, это не последний элемент. Это работает на обоих разреженных и смежных массивов, хотя:

$ echo ${array[@]: -1} 
i 
+2

Отличный материал; никогда не знал, что синтаксис подстроки-экстракции может быть применен и к массивам; правила, определяемые методом проб и ошибок, являются (bash 3.2.48): '$ {array [@]: start [: count]}' Возвращает count elems. или, если не указано, все _remaining_ elems. начиная с следующего элемента: - Если пуск> = 0: из элем. индекс которого = = начало. - При запуске <0: с элем. индекс которого равен (последний индекс массива + 1) - abs (начало); CAVEAT: если abs (начало)> (последний индекс массива + 1), возвращается пустая строка. Если указано количество, возвращается столько элементов, даже если их индексы не смежны от начала. – mklement0

+2

@mklement: В Bash 4.2 вы можете использовать индексы отрицательного массива для доступа к элементам, подсчитываемым с конца массива. '$ {array [-1]}' –

+0

Это хорошо, спасибо. OS X (по состоянию на 10.8.2) все еще использует 3.2.48, а http://stackoverflow.com/questions/10418616/does-darwin-macos-modify-bash говорит мне, что, к сожалению, «Apple использует довольно старую версию Bash, так как они не отправляют код, лицензированный под GPL3 ». – mklement0

1

С индексный массив, вы можете что-то вроде этого:

declare -a a=() 
a+=('foo' 'bar')