Доступ к элементам массива

Итак, где могут пригодиться массивы? Так же как многие задачи управления данными могут решаться с применением программ электронных таблиц, массивы могут применяться для решения множества задач программирования.

Рассмотрим простой пример сбора и представления данных. Напишем сценарий, проверяющий время последнего изменения файлов в указанном каталоге. На основе полученных данных сценарий будет выводить таблицу, показывающую, сколько файлов было изменено в каждый час суток. Такой сценарий можно использовать, например, для выяснения периодов наибольшей активности системы. Сценарий с названием hours производит следующий результат:

[me@linuxbox ~]$ hours .

Hour Files Hour Files

---- ----- ---- -----

00 0 12 11

01 1 13 7

02 0 14 1

03 0 15 7

04 1 16 6

05 1 17 5

06 6 18 4

07 3 19 4

08 1 20 1

09 14 21 0

10 2 22 0

11 5 23 0

Total files = 80

В этом примере мы запустили программу hours, передав ей текущий каталог для анализа. Она вывела таблицу, показывающую число файлов, изменявшихся в каждый час суток (0–23). Ниже показан код, осуществляющий вывод этой таб­лицы:

#!/bin/bash

# hours : сценарий для подсчета файлов по времени изменения

usage () {

echo "usage: $(basename $0) directory" >&2

}

# Убедиться, что аргумент является каталогом

if [[ ! -d $1 ]]; then

usage

exit 1

fi

# Инициализировать массив

for i in {0..23}; do hours[i]=0; done

# Собрать данные

for i in $(stat -c %y "$1"/* | cut -c 12-13); do

j=${i/#0}

((++hours[j]))

((++count))

done

# Вывести данные

echo -e "Hour Files Hour Files"

echo -e "---- ----- ---- -----"

for i in {0..11}; do

j=$((i + 12))

printf "%02d %d %02d %d " $i ${hours[i]} $j ${hours[j]}

done

printf " Total files = %d " $count

Сценарий состоит из одной функции (usage) и основного тела с четырьмя разделами. В первом разделе проверяется, является ли аргумент командной строки именем каталога. Если нет, сценарий выводит сообщение с информацией о порядке использования и завершается.

Второй раздел инициализирует массив hours. Для этого каждому элементу массива присваивается значение 0. Массивы не требуют специальной инициализации перед использованием, но нашему сценарию важно, чтобы в массиве не оставалось элементов с пустыми значениями. Обратите внимание на необычный способ организации цикла. Используя подстановку в фигурных скобках ({0..23}), мы смогли без труда сгенерировать последовательность слов для команды for.

Следующий раздел осуществляет сбор данных, вызывая программу stat для каждого файла в каталоге. С помощью cut из результата извлекается двузначный час. Внутри цикла выполняется удаление ведущих нулей из поля с часом, потому что иначе командная оболочка попытается (и, в конечном счете, потерпит неудачу) интерпретировать значения с 00 по 09 как восьмеричные числа (см. табл. 34.1). Далее сценарий увеличивает на единицу значение элемента массива, соответствующего полученному часу дня. Наконец, будет увеличен счетчик (count), хранящий общее число файлов в каталоге.

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