Массив в цикле bash не работает вне цикла [duplicate]

В любом случае, когда есть сомнения, используйте скобки!

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

Но опять же, я не знаком с python.

548
задан codeforester 2 June 2017 в 20:08
поделиться

5 ответов

Да, есть:

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

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

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

1087
ответ дан Etienne Dechamps 15 August 2018 в 16:21
поделиться
  • 1
    Это отлично работает с bash 3.2.48 (OS X 10.8.2). Обратите внимание, что ARRAY является просто заполнителем для фактического имени переменной. Даже если ваши индексы массива не последовательно, добавление с помощью += будет просто присвоено наивысшему индексу + 1. – mklement0 21 September 2012 в 04:01
  • 2
    Есть ли что-то подобное в bash версии 4.2.24 (1)? – Ali Ismayilov 1 December 2012 в 14:51
  • 3
    Важно отметить, что ARRAY if = ('foo') отличается от ARRAY = 'foo', который добавляет строку 'foo' к записи с наименьшим (?) Ключом. – TheConstructor 3 May 2013 в 14:17
  • 4
    Согласно wiki.bash-hackers.org/scripting/bashchanges , этот синтаксис впервые появился в версии 3.1-alpha1. – David Yaw 3 January 2014 в 23:17
  • 5
    @Jas: Чтобы получить доступ к массиву whole , вы должны использовать ${myarray[@]} - ссылка на переменную массива, как если бы она была скаляром, такая же, как и обращение к ее элементу 0; другими словами: $myarray совпадает с ${myarray[0]}. – mklement0 13 May 2015 в 17:25

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

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

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

16
ответ дан cafebabe1991 15 August 2018 в 16:21
поделиться
  • 1
    Да, вы можете, но синтаксис += (см. Ответ @ e-t172) проще (a), и (b) также работает с массивами, которые не являются смежными и / или не начинаются с 0. – mklement0 21 September 2012 в 04:06
  • 2
    Честно говоря, это решение (для меня) работает лучше, чем «+ =», потому что с последним длина иногда ошибочна (увеличивается на два при добавлении одного элемента) ... поэтому я предпочитаю этот ответ! :) – Pierpaolo Cira 3 December 2017 в 16:51

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

declare -a a=()
a+=('foo' 'bar')
2
ответ дан codeforester 15 August 2018 в 16:21
поделиться

Как указывает 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
58
ответ дан Dennis Williamson 15 August 2018 в 16:21
поделиться
  • 1
    Качественный товар; никогда не знал, что синтаксис подстроки-экстракции может быть применен и к массивам; правила, определяемые методом проб и ошибок, (bash 3.2.48): ${array[@]: start[:count]} Возвращает count elems. или, если не указано, все остальные elems. начиная с следующего элемента: - Если start & gt; = 0: от элемента. индекс которого & gt; = start. - Если start & lt; 0: от элемента. индекс которого равен (последний индекс массива + 1) - abs (начало); CAVEAT: если abs (начало) & gt; (последний индекс массива + 1), возвращается пустая строка. Если указано количество, возвращаемое количество элементов, даже если их индексы не смежны от начала. – mklement0 21 September 2012 в 06:47
  • 2
    @mklement: В Bash 4.2 вы можете использовать отрицательные индексы массивов для доступа к элементам, подсчитываемым с конца массива. ${array[-1]} – Dennis Williamson 21 September 2012 в 16:02
  • 3
    Это хорошо, спасибо. OS X (по состоянию на 10.8.2) все еще использует 3.2.48, а stackoverflow.com/questions/10418616/… сообщает мне, что, к сожалению, «Apple использует довольно старую версию Bash, поскольку они не отправляют код, лицензированный под GPL3. & quot; – mklement0 21 September 2012 в 16:29
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest
36
ответ дан Zenexer 15 August 2018 в 16:21
поделиться
  • 1
    подходит для версий bash, которые не поддерживают семантику оператора + =, объясняемого e-t172 – akostadinov 14 September 2012 в 20:26
  • 2
    хорошее обратное совместимое решение, но будьте осторожны, если любой из существующих элементов имеет в них пробелы, они будут разбиты на несколько элементов; используйте arr=("${arr[@]}" "new"), если у вас есть элементы с пробелами в них – kbolino 17 March 2013 в 18:50
  • 3
    Это также можно использовать для нажатия перед массивом, что является именно тем, что мне нужно. – Tomáš Zato 8 October 2015 в 08:17
Другие вопросы по тегам:

Похожие вопросы: