× К оглавлению На главную Об авторе
## 1. Назначение Нужно понимать, что в классическом Bash нет «настоящей» поддержки многомерных массивов. Однако есть несколько способов имитации или симуляции двухмерных структуры данных: * Использовать ассоциативный массив (требуется Bash 4.0 и выше), * Хранить каждый «ряд» в отдельном массиве, * Одномерный массив и расчёт индекса вручную. Дополнительные советы: * Если нужно часто оперировать «двумерностью» в скриптах, лучше сразу перейти к языкам, где есть полноценные многомерные массивы (например, Python, Perl и т.д.). В Bash же это всегда будет workaround. * При большом объёме данных и сложных структурах производительность Bash может стать узким местом — возможно, имеет смысл использовать более специализированный язык или инструменты (AWK, Python). * Для ассоциативных массивов предпочтительнее Bash 4.4+: в ранних версиях (4.0–4.3) встречались отдельные ошибки при работе с массивами. Таким образом, наиболее универсальный и гибкий способ для Bash 4.x+ — это использование ассоциативного массива с составным ключом "row,col". Если по каким-то причинам это невозможно (или нужна совместимость со старыми системами), можно использовать одно из обходных решений: ряд отдельных массивов или линейное хранение всех элементов с ручным пересчётом индексов. ## 2. Использование ### 2.1 Использовать ассоциативный массив (требуется Bash 4.0 и выше) В современных версиях Bash можно создавать ассоциативные массивы и применять их в качестве псевдодвухмерных. Сначала объявляем ассоциативный массив:

    declare -A matrix

Заполняем его, указывая в качестве ключа пару «строка,столбец»:

    matrix["0,0"]="A0"
    matrix["0,1"]="B0"
    matrix["1,0"]="A1"
    matrix["1,1"]="B1"

Читаем элементы по тому же ключу:

    echo "${matrix["0,0"]}"  # Выведет A0
    echo "${matrix["1,1"]}"  # Выведет B1

Для перебора всех элементов удобно использовать конструкции вида:

    for key in "${!matrix[@]}"; 
      do
          echo "Ключ: $key Значение: ${matrix[$key]}"
      done

Если нужно отдельно обработать «строку» и «столбец», можно разбить key по разделителю (запятая в данном примере):

    IFS="," read -r row col <<< "$key"

Таким образом, «двухмерность» получается за счёт комбинирования индексов (строка, столбец) в один ассоциативный ключ, что дает свои плюсы и минусы: **Плюсы** * Простая реализация в коде. * Гибкость — можно хранить любые комбинации «строка, столбец». * Приятно работают функции Bash для ассоциативных массивов (итерация, проверка наличия ключей и т.п.). **Минусы** * Нет жёсткой привязки к реальному количеству строк и столбцов — ключи могут быть как угодно «разрежены». * Нужно помнить, что ключ — это строка, и что внутри него есть разделитель (запятая): если в индексе теоретически могут встречаться другие символы (например, пробел), придётся аккуратно экранировать или выбирать другой разделитель. ### 2.2 Хранить каждый «ряд» в отдельном массиве Можно заведённую структуру представить в виде:

    row0=( "A0" "B0" )
    row1=( "A1" "B1" )

Чтобы обратиться к элементу, достаточно использовать имя соответствующего массива и индекс:

    echo "${row0[0]}"  # A0
    echo "${row1[1]}"  # B1

Если нужно перебрать все элементы «матрицы», придётся обходить каждый массив по отдельности. Такой подход дает свои плюсы и минусы: **Плюсы** * Наглядный доступ к элементам: row, col очевидно распределены по переменным. * Не требует Bash 4.0, работает в старых версиях. **Минусы** * Потребуется более сложный код, если количество «рядов» динамическое. Нужно уметь обращаться к элементам по имени массива (например, используя индирекцию). * Имена массивов могут стать громоздкими, если строк и столбцов много. ### 2.3 Одномерный массив и расчёт индекса вручную Имитируем «двухмерность», используя один массив:

    declare -a array_1d

Для индексации используем формулу: index = row * (числостолбцов) + col. Рассмотрим пример:

    # Предположим, у нас 2 строки и 2 столбца
    array1d[ 0 * 2 + 0 ]="A0"
    array1d[ 0 * 2 + 1 ]="B0"
    array1d[ 1 * 2 + 0 ]="A1"
    array_1d[ 1 * 2 + 1 ]="B1"

Доступ к элементам (например, row=1, col=0):

    idx=$((row*2 + col))
    echo "${array_1d[$idx]}"  # A1

Плюсы и минусы такого подхода: **Плюсы** * Работает во всех версиях Bash — не нужны ассоциативные массивы. * Можно хранить ровную матрицу в плане индексов (не будет «пропусков»). **Минусы** * При больших размерах матрицы код может выглядеть менее наглядно. * Нужно заранее знать (или хранить) количество столбцов для расчёта индекса.