Посібник із масивів Bash

Основи роботи з масивами в Bash

У цьому посібнику ми детально розглянемо, як створювати та використовувати масиви в Bash, включаючи індексовані та асоціативні масиви.

Масиви в Bash є потужним інструментом для зберігання набору елементів в одній змінній. На відміну від деяких інших мов програмування, Bash дозволяє зберігати в одному масиві дані різних типів, такі як числа та рядки. Важливо зазначити, що масиви Bash є одновимірними.

Ми пройдемося по всіх етапах: від оголошення масиву, доступу до його елементів, ітерації по масиву та додавання нових елементів. На завершення, розглянемо, що таке асоціативні масиви та як їх застосовувати.

Отже, почнімо!

Перш ніж продовжити, переконайтеся, що у вас встановлено Bash.

Оголошення масивів у Bash

У цьому розділі ми розглянемо синтаксис оголошення масиву та наведемо приклади коду.

Синтаксис

Для оголошення масиву в Bash використовується наступний синтаксис:

arrayName=(елемент1 елемент2 ... елементN)

# arrayName - назва масиву
# елемент1, елемент2, ..., елементN - елементи масиву

У наведеному прикладі arrayName є ідентифікатором масиву, а елементи масиву (елемент1 до елементN) вказуються у круглих дужках і розділені пробілами. Важливо пам’ятати, що при присвоєнні значень не повинно бути пробілів перед або після знака “=”.

Варто зазначити, що в більшості мов програмування елементи масиву відокремлюються комами, але в Bash використовується пробіл.

Масиви, в яких доступ до елементів здійснюється за індексом, називаються індексованими масивами.

Приклад індексованого масиву

Розглянемо приклад створення масиву з назвою “ціни”, що містить числові значення:

prices=(24 27 18 30 15)

Як видно з синтаксису, числа в масиві “ціни” розділені пробілами та вказані в дужках.

Щоб вивести значення змінної в Bash, використовується команда echo. Проте, якщо просто вивести ім’я масиву, ви отримаєте лише перший його елемент.

echo $prices
# Виведе: 24

В Bash індексація масивів починається з нуля. Тобто, перший елемент має індекс 0, другий – 1, і так далі. Можливе також використання від’ємних індексів, де -1 відповідає останньому елементу.

Що ж станеться, якщо ми спробуємо вивести елемент за певним індексом, наприклад, з індексом 1?

echo $prices[1]
# Виведе: 24[1]

Чому результат саме “24[1]”? 🤔 Це тому, що Bash замінює $prices на 24, перший елемент масиву, а “[1]” виводить як звичайний текст.

Щоб вивести елемент за конкретним індексом, потрібно використовувати формат ${prices[index]}.

echo ${prices[1]}
# Виведе: 27
echo ${prices[2]}
# Виведе: 18

Щоб вивести всі елементи масиву, потрібно використовувати символ @ замість індексу.

echo ${prices[@]}
# Виведе: 24 27 18 30 15

Далі створимо масив рядків. Ось як можна оголосити індексований масив:

declare -a fruits

Ключове слово -a створює індексований масив. Тепер ми можемо заповнити масив, додаючи елементи один за одним за конкретним індексом, як показано далі:

fruits[0]="cherry"
fruits[1]="berry"
fruits[2]="apple"
fruits[3]="pear"
fruits[4]="melon"
fruits[5]="orange"

Тепер, щоб роздрукувати всі елементи масиву, використовуємо ${fruits[@]}.

echo ${fruits[@]}
# Виведе: cherry berry apple pear melon orange

Як отримати доступ до елементів масиву

Існує два основних способи доступу до елементів масиву:

  • Перебір усіх елементів масиву.
  • Доступ до елементів за індексом.

Перебір елементів масиву

В Python, для перебору списку використовується цикл for у такому вигляді:

for elt in some_list:
    print(elt)

Аналогічний цикл в Bash має дещо інший синтаксис.

Ми вже знаємо, що ${prices[@]} виводить всі елементи масиву “ціни”. Тепер створимо цикл for для перебору цих елементів.

У Bash оператори тіла циклу повинні бути укладені між do та done:

for price in ${prices[@]}
do
    echo $price
done

Оскільки ми використовуємо команду echo для друку значення змінної “price”, ми отримаємо наступний результат:

# Виведе:
24
27
18
30
15

Доступ до елементів за індексом

Інший спосіб перебору масиву полягає у використанні індексів. Це аналогічно конструкції циклу for з функцією range() в Python:

for i in range(len(some_list)):
    print(i)

Щоб отримати список індексів, потрібно поставити знак оклику (!) перед ім’ям масиву у виразі розширення параметра. Це виведе список всіх валідних індексів:

echo ${!prices[@]}
# Виведе: 0 1 2 3 4

Масив “ціни” містить 5 елементів, отже індекси починаються з 0 і закінчуються на 4.

Тепер ми можемо перебрати всі індекси і отримати доступ до елементів масиву. Для індексу i елемент масиву можна отримати як ${prices[i]}.

for i in ${!prices[@]}
do
    echo ${prices[i]}
done

Цей цикл виведе всі елементи масиву:

# Виведе:
24
27
18
30
15

В даному випадку ми просто виводимо значення кожного елемента. В цілому, ми можемо виконувати будь-яку обробку елементів у тілі циклу.

Як додати елементи до масиву

В масиві “ціни” у нас вже є 5 елементів (з індексами 0, 1, 2, 3 і 4). Якщо потрібно додати новий елемент в кінець масиву (з індексом 5), це можна зробити так:

prices[5]=21

Тепер в кінці масиву з’явиться значення 21.

echo ${prices[@]}
# Виведе: 24 27 18 30 15 21

Проте, зручніше додавати елементи до масиву, не запам’ятовуючи індекс останнього елемента або їх загальну кількість.

Для цього можна скористатися конструкцією arrayName+=(element(s)), яка додає один або кілька елементів до кінця масиву:

prices+=(10)

Тепер, якщо ми виведемо масив “ціни”, ми побачимо, що значення 10 було додане в його кінець:

echo ${prices[@]}
# Виведе: 24 27 18 30 15 21 10

Далі ми розглянемо, як оголошувати асоціативні масиви в Bash.

Асоціативні масиви

Асоціативні масиви використовуються для представлення пар “ключ-значення”. Їх можна оголосити за допомогою наступного синтаксису, де ми використовуємо параметр -A замість -a:

declare -A fruits_prices

Тепер ми можемо додавати елементи до асоціативного масиву, вказуючи ключ і відповідне значення. У цьому прикладі ми використовуємо назви фруктів як ключі, а числа з масиву “ціни” як значення:

fruits_prices[cherry]=24
fruits_prices[berry]=27
fruits_prices[apple]=18
fruits_prices[pear]=30
fruits_prices[melon]=15
fruits_prices[orange]=21

Як же отримати доступ до елементів асоціативного масиву?

Подібно до словників у Python, ви можете отримувати значення, використовуючи відповідний ключ:

echo ${fruits_prices[berry]}
# Виведе: 27

${fruits_prices[@]} виведе всі значення, а ${!fruits_prices[@]} виведе всі ключі:

echo ${fruits_prices[@]}
# Виведе: 18 27 21 24 30 15
echo ${!fruits_prices[@]}
# Виведе: apple berry orange cherry pear melon

Зауважте, що порядок елементів не збігається з порядком їх додавання. Це тому, що, на відміну від індексованих масивів, асоціативні масиви не є впорядкованими колекціями. Вони працюють на зв’язках між ключами та значеннями. Таким чином, ключі в асоціативних масивах відіграють ту ж роль, що й індекси в індексованих масивах.

Ви також можете перебрати асоціативний масив і отримати доступ до ключів:

for key in ${!fruits_prices[@]}
do
    echo $key
done
# Виведе:
apple
berry
orange
cherry
pear
melon

А наступний цикл показує, як можна отримати доступ до значень:

for value in ${fruits_prices[@]}
do
    echo $value
done
# Виведе:
18
27
21
24
30
15

Хоча зазвичай для додавання елементів використовується синтаксис arrayName[key]=value, можна також оголосити асоціативний масив як послідовність:

declare -A arrayName
arrayName=(key1 value1 key2 value2 ... keyN valueN)

В цьому випадку Bash буде інтерпретувати перший елемент як перший ключ, другий як перше значення, і так далі.

Підсумки

Сподіваємося, цей посібник допоміг вам зрозуміти, як створювати та використовувати масиви в Bash. Ось короткий огляд основних моментів:

  • Індексовані масиви можна оголосити за допомогою синтаксису arrayName=(елемент1 елемент2 елемент3 … елементN) або за допомогою команди declare -a arrayName з подальшим додаванням елементів.
  • Для доступу до елементів можна використовувати цикл ${arrayName[@]}. Також можна отримати список всіх валідних індексів, використовуючи розширення параметра ${!arrayName[@]}.
  • Ми також розглянули, як створювати асоціативні масиви для зберігання пар “ключ-значення”.

Наступним кроком може бути вивчення роботи з циклами в Bash.