1 #!/bin/bash
2 # query2.sh
3
4 numbers=(53 8 12 9 784 69 8 7 1)
5 i=4
6
7 echo ${numbers[@]} # <--- this echoes "53 8 12 9 784 69 8 7 1" to stdout.
8 echo ${numbers[i]} # <--- this echoes "784" to stdout.
9
10 unset numbers[i]
11
12 echo ${numbers[@]} # <--- this echoes "53 8 12 9 69 8 7 1" to stdout.
13 echo ${numbers[i]} # <--- stdout is blank.
Почему в строке 13 пустой вывод stdout, учитывая, что массив, по-видимому, обновлен, судя по выводу строки 12?
И поэтому, что я должен сделать, чтобы получить намеченный ответ, «69»?
Ответы:
unset
удаляет элемент Он не перенумеровывает оставшиеся элементы.Мы можем использовать,
declare -p
чтобы точно узнать, что происходит сnumbers
:Заметьте, что
numbers
больше не имеет элемента4
.Другой пример
Заметим:
Массив
a
не имеет элементов со 2 по 21. Bash не требует, чтобы индексы массива были последовательными.Предложенный метод принудительного перенумерации индексов
Начнем с
numbers
массива с отсутствующим элементом4
:Если мы хотим, чтобы индексы изменились, то:
Теперь есть номер элемента,
4
и он имеет значение69
.Альтернативный метод удаления массива элемента и перенумерации за один шаг
Опять давайте определимся
numbers
:Как предложил Тоби Спейт в комментариях, метод удаления четвертого элемента и перенумерации остальных элементов за один шаг:
Как видите, четвертый элемент был удален, а все остальные элементы были перенумерованы.
${numbers[@]:0:4}
массив ломтиковnumbers
: он принимает первые четыре элемента, начиная с элемента 0.Аналогично,
${numbers[@]:5}
массив фрагментовnumbers
: он принимает все элементы, начиная с элемента 5 и заканчивая концом массива.Получение индексов массива
Эти значения массива могут быть получены с
${a[@]}
. Чтобы найти индексы (или ключи ), которые соответствуют этим значениям, используйте${!a[@]}
.Например, рассмотрим снова наш массив
numbers
с отсутствующим элементом4
:Чтобы увидеть, какие индексы присваиваются:
Опять же,
4
отсутствует в списке индексов.Документация
От
man bash
:источник
a=()
, переменнаяa
все еще не определена, пока вы не назначите один из ее индексов.unset numbers[4]
, присвоить весь массив , используя нарезку, то естьnumbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
(я вывесил бы в ответ, но не имею времени , чтобы правильно объяснить).bash
массивы, подобные inksh
, на самом деле не являются массивами, они больше похожи на ассоциативные массивы с ключами, ограниченными положительными целыми числами (или так называемыми разреженными массивами ). Для оболочки с реальными массивами, вы можете посмотреть на оболочках , какrc
,es
,fish
,yash
,zsh
(или дажеcsh
/tcsh
если эти оболочки имеют так много проблем , они лучше избегать).В
zsh
:(Обратите внимание, что в zsh
unset 'a[3]'
фактически устанавливает пустую строку для лучшей совместимости сksh
)в
yash
:в
fish
(не Bourne-подобная оболочка вопрекиbash
/zsh
):в
es
(на основеrc
, а не по Борну)в
ksh
иbash
Вы можете использовать массивы как обычные, если вы делаете:
после каждой операции удаления или вставки, которая могла сделать список индексов несмежным или не начинаться с 0. Также обратите внимание, что
ksh
/bash
массивы начинаются с 0, а не с 1 (за исключением$@
(в некоторых отношениях)).Это фактически приведет в порядок элементы и переместит их в индекс 0, 1, 2 ... в последовательности.
Также обратите внимание, что вам нужно указать
number[i]
в:В противном случае это будет рассматриваться как
unset numberi
файл, вызываемыйnumberi
в текущем каталоге.источник