Добавить новый элемент в массив без указания индекса в Bash

579

Есть ли способ сделать что-то вроде PHPs $array[] = 'foo'; в bash против выполнения:

array[0] = 'foo'
array[1] = 'bar'
Теги:
arrays

5 ответов

1040
Лучший ответ

Да, есть:

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

Bash Справочное руководство:

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

  • 16
    Это прекрасно работает с bash 3.2.48 (OS X 10.8.2). Обратите внимание, что ARRAY - это просто заполнитель для фактического имени переменной. Даже если индексы вашего массива не последовательные, добавление с += просто присвоит наибольший индекс + 1.
  • 3
    Есть ли что-то подобное в bash версии 4.2.24 (1)?
Показать ещё 13 комментариев
60

Как указывает Dumb 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
  • 3
    Качественный товар; никогда не знал, что синтаксис извлечения подстрок можно применять и к массивам; правила, определенные методом проб и ошибок, (bash 3.2.48): ${array[@]: start[:count]} Возвращает количество элементов. или, если не указано, все остальные элементы. начиная со следующего элемента .: - Если старт> = 0: от элемента. чей индекс> = начало. - Если начало <0: от элемента. чей индекс (последний индекс массива + 1) - abs (начало); CAVEAT: если abs (start)> (последний индекс массива + 1), возвращается пустая строка. Если указано количество, возвращается столько элементов, даже если их индексы не являются смежными с самого начала.
  • 3
    @mklement: в Bash 4.2 вы можете использовать отрицательные индексы массива для доступа к элементам, считающим с конца массива. ${array[-1]}
Показать ещё 1 комментарий
36
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest
  • 5
    хорошо для версий bash, которые не поддерживают семантику оператора + =, объясненного e-t172
  • 10
    хорошее обратно-совместимое решение, но имейте в виду, что если в каком-либо из существующих элементов есть пробелы, они будут разбиты на несколько элементов; используйте arr=("${arr[@]}" "new") если у вас есть элементы с пробелами в них
Показать ещё 1 комментарий
16

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

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

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

  • 4
    Да, вы можете, но синтаксис += (см. Ответ @ e-t172) (а) проще, и (б) также работает с массивами, которые не являются смежными и / или не начинаются с 0.
  • 0
    Честно говоря, это решение (для меня) работает лучше, чем «+ =», потому что с последним длина иногда неверна (увеличивается на два при добавлении одного элемента) ... поэтому я предпочитаю этот ответ! :)
2

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню