Командная строка Linux
Шрифт:
Создание массива
Переменным-массивам можно давать такие же имена, что и другим переменным bash, и они точно так же создаются автоматически при первом обращении к ним. Например:
[me@linuxbox ~]$ a[1]=foo
[me@linuxbox ~]$ echo ${a[1]}
foo
Это пример присваивания значения элементу массива и обращения к нему. Первая команда присваивает значение foo элементу массива a с индексом 1. Вторая команда выводит значение, хранящееся в элементе с индексом 1. Использование
Массив можно также создать командой declare:
[me@linuxbox ~]$ declare -a a
Параметр -a в этом примере требует от declare создать массив (array) с именем a.
Присваивание значений массиву
Значения элементам массивов можно присваивать одним из двух способов. Присваивание одиночных значений осуществляется с использованием следующего синтаксиса:
имя[индекс]=значение
где имя — это имя массива, индекс — целое число (или арифметическое выражение) больше или равное 0. Обратите внимание, что первый элемент массива имеет индекс 0, а не 1. значение — строка или целое число, присваиваемое элементу массива.
Присвоить сразу множество значений можно с использованием следующего синтаксиса:
имя=(значение1значение2 ...)
где имя — это имя массива, а значение1 значение1 ... — значения, присваиваемые последовательным элементам массива, начиная с элемента с индексом 0. Например, если понадобится присвоить элементам массива days сокращенные названия дней недели, это можно сделать так:
[me@linuxbox ~]$ days=(Sun Mon Tue Wed Thu Fri Sat)
Можно присваивать значения конкретным элементам, указывая индекс для каждого значения:
[me@linuxbox ~]$ days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)
Доступ к элементам массива
Итак, где могут пригодиться массивы? Так же как многие задачи управления данными могут решаться с применением программ электронных таблиц, массивы могут применяться для решения множества задач программирования.
Рассмотрим простой пример сбора и представления данных. Напишем сценарий, проверяющий время последнего изменения файлов в указанном каталоге. На основе полученных данных сценарий будет выводить таблицу, показывающую, сколько файлов было изменено в каждый час суток. Такой сценарий можно использовать, например, для выяснения периодов наибольшей активности системы. Сценарий с названием 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
В
#!/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\tFiles\tHour\tFiles"
echo -e "----\t-----\t----\t-----"
for i in {0..11}; do
j=$((i + 12))
printf "%02d\t%d\t%02d\t%d\n" $i ${hours[i]} $j ${hours[j]}
done
printf "\nTotal files = %d\n" $count
Сценарий состоит из одной функции (usage) и основного тела с четырьмя разделами. В первом разделе проверяется, является ли аргумент командной строки именем каталога. Если нет, сценарий выводит сообщение с информацией о порядке использования и завершается.
Второй раздел инициализирует массив hours. Для этого каждому элементу массива присваивается значение 0. Массивы не требуют специальной инициализации перед использованием, но нашему сценарию важно, чтобы в массиве не оставалось элементов с пустыми значениями. Обратите внимание на необычный способ организации цикла. Используя подстановку в фигурных скобках ({0..23}), мы смогли без труда сгенерировать последовательность слов для команды for.
Следующий раздел осуществляет сбор данных, вызывая программу stat для каждого файла в каталоге. С помощью cut из результата извлекается двузначный час. Внутри цикла выполняется удаление ведущих нулей из поля с часом, потому что иначе командная оболочка попытается (и, в конечном счете, потерпит неудачу) интерпретировать значения с 00 по 09 как восьмеричные числа (см. табл. 34.1). Далее сценарий увеличивает на единицу значение элемента массива, соответствующего полученному часу дня. Наконец, будет увеличен счетчик (count), хранящий общее число файлов в каталоге.
Последний раздел в сценарии выводит содержимое массива. Сначала выводится пара строк заголовка, а затем начинает выполняться цикл, осуществляющий вывод в четыре колонки. В заключение выводится общее число файлов.
Операции с массивами
Массивы поддерживают множество типовых операций, таких как удаление массивов, определение их размеров, сортировка и др., которым можно найти много вариантов применения в сценариях.
Вывод содержимого всего массива