В этом руководстве мы рассмотрим, как использовать массивы в bash и выполнять над ними фундаментальные операции.
Bash, Bourne Again Shell, является оболочкой по умолчанию практически во всех основных дистрибутивах linux: он действительно мощный и может также рассматриваться как язык программирования, хотя и не такой сложный и функциональный, как python или другие “правильные” языки.
Более того, написание скриптов Bash является обязательным навыком для любого системного администратора Linux.
Основная цель массива Bash – хранить информацию в индексированном виде. Э
то работает так же, как хранение информации внутри переменных, за исключением того, что это также дает нам возможность вызывать информацию, используя индексированные и предсказуемые числа.
Мы также можем использовать массивы для создания ассоциаций.
Если вы работаете со скриптом, который должен хранить большое количество информации, массивы Bash станут необходимым компонентом.
- Создание массива
- Создание индексированных или ассоциативных массивов с помощью команды declare
- Создание индексированных массивов на лету
- Операции с массивами Bash
- Вывести значения массива
- Вывод ключей массива bash
- Получение размера массива bash
- Добавление элементов в массив bash
- Удаление элемента из массива bash
- Заключение
Создание массива
Прежде всего, необходимо провести различие между индексированным массивом bash и ассоциативным массивом bash.
Первые – это массивы, в которых ключами являются упорядоченные целые числа, а вторые – массивы, в которых ключи представлены строками.
Хотя индексированные массивы можно инициализировать различными способами, ассоциативные массивы можно создать только с помощью команды declare, как мы увидим через некоторое время.
Создание индексированных или ассоциативных массивов с помощью команды declare
Мы можем явно создать массив с помощью команды declare:
$ declare -a my_array
Объявление, в bash, используется для задания переменных и атрибутов.
В данном случае, поскольку мы указали опцию -a, был создан индексированный массив с именем my_array.
Ассоциативные массивы могут быть созданы таким же образом: единственное, что нам нужно изменить, это используемую опцию: вместо строчной -a мы должны использовать опцию -A команды declare:
$ declare -A my_array
Это, как уже было сказано, единственный способ создания ассоциативных массивов в bash.
Создание индексированных массивов на лету
Мы можем создавать индексированные массивы с помощью более лаконичного синтаксиса, просто присваивая им некоторые значения:
$ my_array=(foo bar)
В данном случае мы присвоили массиву сразу несколько элементов, но мы также можем вставлять по одному значению за раз, указывая его индекс:
$ my_array[0]=foo
Операции с массивами Bash
После создания массива мы можем выполнять с ним некоторые полезные операции.
Например, отобразить его ключи и значения или изменить его, добавив или удалив элементы:
Вывести значения массива
Чтобы вывести все значения массива, мы можем использовать следующий синтаксис:
$ echo ${my_array[@]}
Или даже:
$ echo ${my_array[*]}
Оба синтаксиса позволяют нам получить доступ ко всем значениям массива и дают одинаковые результаты, если только расширение не заключено в кавычки.
В этом случае возникает разница: в первом случае, при использовании @, расширение приведет к тому, что для каждого элемента массива будет указано слово.
Это сразу становится понятно при выполнении цикла for.
В качестве примера представьте, что у нас есть массив с двумя элементами, “foo” и “bar”:
$ my_array=(foo bar)
Выполнение цикла for приведет к следующему результату:
$ for i in "${my_array[@]}"; do echo "$i"; done foo bar
При использовании *, когда переменная заключена в кавычки, вместо нее будет получен один “результат”, содержащий все элементы массива:
$ for i in "${my_array[*]}"; do echo "$i"; done foo bar
Вывод ключей массива bash
Можно даже получить и вывести ключи, используемые в индексированном или ассоциативном массиве, вместо их соответствующих значений.
Синтаксис почти идентичен, но основан на использовании оператора !
$ my_array=(foo bar baz) $ for index in "${!my_array[@]}"; do echo "$index"; done 0 1 2
То же самое справедливо и для ассоциативных массивов:
$ declare -A my_array $ my_array=([foo]=bar [baz]=foobar) $ for key in "${!my_array[@]}"; do echo "$key"; done baz foo
Как видите, поскольку последний является ассоциативным массивом, мы не можем рассчитывать на то, что извлеченные значения будут возвращены в том же порядке, в котором они были объявлены.
Получение размера массива bash
Мы можем получить размер массива (количество элементов, содержащихся в нем), используя специальное расширение оболочки:
$ my_array=(foo bar baz) $ echo "the array contains ${#my_array[@]} elements" the array contains 3 elements
Мы создали массив, который содержит три элемента, “foo”, “bar” и “baz”, затем, используя приведенный выше синтаксис, который отличается от того, который мы видели ранее для получения значений массива только символом # перед именем массива, мы получили количество элементов в массиве вместо его содержимого.
Добавление элементов в массив bash
Как мы видели, мы можем добавлять элементы в индексированный или ассоциативный массив, указывая соответственно их индекс или ассоциативный ключ.
В случае с индексированными массивами мы также можем просто добавить элемент, добавив его в конец массива с помощью оператора +=:
$ my_array=(foo bar) $ my_array+=(baz)
Если мы теперь выведем содержимое массива, то увидим, что элемент был успешно добавлен:
$ echo "${my_array[@]}" foo bar baz
Одновременно можно добавлять несколько элементов:
$ my_array=(foo bar) $ my_array+=(baz foobar) $ echo "${my_array[@]}" foo bar baz foobar
Чтобы добавить элементы в ассоциативный массив, мы должны указать также их связанные ключи:
$ declare -A my_array
# Add single element
$ my_array[foo]="bar"
# Add multiple elements at a time
$ my_array+=([baz]=foobar [foobarbaz]=baz)
Удаление элемента из массива bash
Чтобы удалить элемент из массива, нам нужно знать его индекс или ключ в случае ассоциативного массива, и использовать команду unset.
Рассмотрим пример:
$ my_array=(foo bar baz) $ unset my_array[1] $ echo ${my_array[@]} foo baz
Мы создали простой массив, содержащий три элемента, “foo”, “bar” и “baz”, затем мы удалили из него “bar”, выполнив unset и обратившись к индексу “bar” в массиве: в данном случае мы знаем, что это была 1, поскольку массивы bash начинаются с 0.
Если мы проверим индексы массива, то увидим, что 1 отсутствует:
$ echo ${!my_array[@]} 0 2
То же самое справедливо для ассоциативных массивов:
$ declare -A my_array $ my_array+=([foo]=bar [baz]=foobar) $ unset my_array[foo] $ echo ${my_array[@]} foobar
В приведенном примере значение, на которое ссылается ключ “foo”, было удалено, в массиве осталось только “foobar”.
Удалить весь массив еще проще: мы просто передаем имя массива в качестве аргумента команде unset, не указывая ни индекса, ни ключа:
$ unset my_array $ echo ${!my_array[@]}
После выполнения unset для всего массива, при попытке вывести его содержимое возвращается пустой результат: массив больше не существует.
Заключение
В этой статье мы рассмотрели разницу между индексированными и ассоциативными массивами в bash.
Затем мы узнали, как их инициализировать и как выполнять основные операции, такие как отображение ключей и значений, добавление или удаление элементов. Наконец, мы увидели, как их полностью удалить.
Синтаксис Bash иногда может быть довольно странным, но использование массивов в скриптах может быть действительно полезным.
Когда скрипт начинает становиться сложнее, чем ожидалось, я советую перейти на более удобный язык, например, python.
см. также: