Вот почему ваши Bash-скрипты всё ещё неидеальны: взрывные трюки с массивами, которыми почти никто не пользуется!

Tux, the Linux mascot, sitting with a laptop in front of a large terminal window.-1

Работая с большим объёмом данных в Bash-скриптах, я понял: массивы — вот что реально спасает мои нервы и экономит часы работы. С виду их синтаксис может напугать, но стоит разобраться — и ваши скрипты становятся компактнее, понятнее и умеют гораздо больше. Переменных в коде становится меньше, а управлять данными — проще и нагляднее.

Как создать массив

В Bash массивы позволяют хранить сколько угодно значений в одной переменной — почти как списки в Python. С их помощью легко организовать имена файлов, логины пользователей, параметры конфигурации или просто массив аргументов команд.

Одна из фишек Bash — заранее не нужно задавать тип массива. Достаточно записать значения особым образом — и Bash сам определит, что перед вами массив. Есть пара вариантов, расскажу обо всех.

Самый частый случай — индексированный массив. Просто напишите имя, знак равно и значения в скобках:

Всё! Массив создан (пусть пока и пустой). Проверить содержимое можно через обычный echo:

Объявление пустого массива и попытка вывести его содержимое через echo.

Результат — пустая строка. Чтобы сразу заполнить массив, просто перечислите элементы через пробел внутри скобок:

Каждое значение попадёт в свой индекс. Проверить легко:

Создание массива с элементами и вывод содержимого через echo.

Массив можно оставить пустым, а наполнять его постепенно — прямо в ходе выполнения скрипта.

Если теперь посмотреть на массив — появятся новые значения.

Пустой массив в Bash и поочередное добавление элементов.

Особенно удобно, если элементы появляются по ходу работы. Можно добавлять значения и по конкретному индексу.

Есть и другой способ — воспользоваться встроенной командой declare, чтобы явно указать, что переменная — это массив.

Так другим сразу понятно, что, например, colors — это именно массив. Посмотреть тип и содержимое переменной всегда можно через declare -p.

Объявление массива с помощью declare и просмотр его содержимого.

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

Как перебрать элементы массива

Создав массив, хочется сразу с ним что-то сделать: напечатать, обработать или передать дальше. В Bash есть несколько простых способов обойти все элементы — они сделают ваши скрипты мощнее и надёжнее.

Самый лёгкий — обычный цикл for Bash:

Перебор элементов массива в Bash через обычный цикл for.

Если нужно знать ещё и индекс каждого элемента — используйте цикл в стиле C:

Перебор массива в стиле C с использованием индексов.

Если интересуют только номера элементов, поможет специальная конструкция ${!array[@]}:

Перебор индексов массива Bash с помощью цикла for.

Это палочка-выручалочка, если у вас «дырявый» массив с удалёнными элементами. А если массив формируется прямо из вывода какой-то команды — цикл while read просто необходим.

Часто применяю этот приём для обработки данных прямо из файлов или входящих команд. А ещё Bash позволяет перебрать сразу несколько массивов в одном цикле. Вот пример:

Один цикл — несколько массивов: перебор в Bash.

Главное — убедитесь, что длины всех массивов одинаковы, иначе легко получить неожиданные ошибки!

Какие бывают массивы в Bash

В Bash есть несколько типов массивов — и если вы знаете отличия, сможете грамотно выбрать нужный вариант для своих задач:

Есть даже разрежённые массивы (sparse) — с пропущенными индексами. Давайте рассмотрим варианты по порядку:

Индексированные массивы

Самый популярный тип — индексированные: идеально подходит для чётких списков вроде имён файлов, чисел или логинов. Каждый элемент имеет числовой индекс, начиная с нуля.

Пример использования индексированного массива.

Всё содержимое массива можно вывести сразу или узнать его длину:

Если важен порядок или нужно пройтись по элементам из команды — этот тип идеален.

Ассоциативные массивы

Ассоциативные массивы в Bash — почти как словари: вместо числового индекса вы задаёте строковый ключ.

Пример: объявление и доступ к элементу ассоциативного массива.

Можно пройтись по всем ключам и их значениям одним циклом:

Перебор ассоциативного массива: выводим пары ключ-значение.

Обратите внимание: Bash не гарантирует порядок ключей! Если нужен определённый порядок — сортируйте ключи вручную. Ассоциативные массивы отлично подходят для пар вида «ключ-значение», например, при обработке данных из JSON.

Разрежённые массивы

Не самая известная, но при этом крайне удобная штука — разрежённые массивы: в них индексы могут идти с пропусками и не по порядку.

Так выглядят разреженные массивы с неупорядоченными индексами.

Если обратиться к несуществующему индексу — получите пустую строку:

А все имеющиеся элементы спокойно перебираются без лишних ошибок. Отлично подходит для «дырок» в данных.

Как получить, изменить и удалить элементы массива

Когда массив заполнен, легко получить нужное значение, поменять его или удалить лишнее — для этого есть простые приёмы и пара нюансов.

В индексированных массивах работаем по номеру, в ассоциативных — по ключу. Например:

Для ассоциативного массива:

Если по запросу значения нет — вы увидите лишь пустую строку. Для работы со всеми элементами или ключами используют специальные конструкции. Вот мини-шпаргалка:

Синтаксис:

Описание

${array[@]}

все значения

${!array[@]}

все индексы или ключи

${#array[@]}

количество элементов

${array[*]}

все значения одной строкой

Обязательно ставьте кавычки вокруг «${array[@]}» — это избавит от неожиданных «разбиений» данных на части, особенно, если элементы содержат пробелы или спецсимволы.

Чтобы изменить значение — просто присвойте новое:

Перезапись элементов массива Bash.

Добавить новый элемент? Ещё проще — просто впишите его в массив:

Добавление нового значения в массив Bash.

Для ассоциативных массивов — изменяйте значения по ключу, всё так же просто.

Замена значения в ассоциативном массиве Bash.

Имейте в виду: новое значение перезапишет предыдущее без предупреждения.

Удалить элемент или сразу весь массив можно через команду unset — выбирайте сами, что потребуется.

Удаление элемента из массива Bash через unset.

Можно убрать сразу несколько элементов одним махом:

Удаление сразу нескольких элементов из массива Bash.

Чтобы очистить массив полностью, просто передайте его имя:

В ассоциативных массивах — всё то же самое, только вместо числа используйте ключ.

Если нужно массово обновить или удалить элементы — используйте цикл для перебора всех значений.

Фишки и крутые приёмы для работы с массивами Bash

Теперь вы знаете, как создавать, перебирать и менять массивы. Но Bash умеет и кое-что посложнее. Вот мои любимые трюки:

Срезы (slicing)

Легко получить из массива только часть — укажите стартовый индекс и длину среза.

start — откуда взять элементы, length — их количество. Позаботьтесь: индексация начинается с нуля! Вот пример:

Работа со срезами массивов Bash на примере.

Получили три центральных значения, начиная со второго. Очень удобно, если нужно обработать только часть данных.

Копирование и объединение массивов

Чтобы скопировать массив, просто присвойте значения другому. В Bash копирование всегда «по значению», так что изменения в новом массиве не повлияют на исходник.

Копируем один массив Bash в другой.

А чтобы объединить несколько массивов — просто «склейте» их элементы через специальный синтаксис:

Объединение двух и более массивов в Bash.

Сортировка

Хотите отсортировать массив по алфавиту или по числам? В Bash для этого нет отдельной команды, но вы легко обойдётесь сторонней утилитой sort:

Сортировка массива Bash по алфавиту в возрастающем порядке.

sort выстроит значения, а IFS=$'\n' защитит от ошибок даже если внутри элементов есть пробелы. Для сортировки по убыванию добавьте к sort нужную опцию.

Для сортировки чисел используйте sort -n:

Числовая сортировка массива Bash по возрастанию.

Удаление дубликатов

Если нужно убрать повторы значений — используйте sort с уникализацией:

Как убрать дубли из массива Bash.

Заодно значения отсортируются. Если исходный порядок важен — фильтруйте дубликаты через ручной цикл и временные переменные.

Фильтрация массива

Быстро выбрать подходящие значения? Для этого подходят шаблоны и расширения Bash:

Фильтрация элементов массива Bash по шаблону.

Крайне полезно, например, для отбора нужных файлов или удаления мусорных данных.

Теперь у вас под рукой мощный набор приёмов для работы с массивами Bash — пробуйте смело все описанные трюки, и ваши скрипты станут проще, а вы — гораздо круче в автоматизации!

Если вам понравилась эта статья, подпишитесь, чтобы не пропустить еще много полезных статей!

Премиум подписка — это доступ к эксклюзивным материалам, чтение канала без рекламы, возможность предлагать темы для статей и даже заказывать индивидуальные обзоры/исследования по своим запросам!

Подробнее о том, какие преимущества вы получите с премиум подпиской, можно узнать здесь

Также подписывайтесь на нас в:

Алекс Бежбакин
Оцените автора
Добавить комментарий