BEGIN {
record="l23#456#789";
split(record, myarray, "#") } END {
for (i in myarray) print myarray[i]
}
Для запуска сценария в качестве входного файла следует указать устройство /dev/null. Если этого не сделать, утилита awk будет ожидать поступления данных с клавиатуры.
$ arraytest.awk /dev/null
123
789
Статические массивы
В предыдущем примере массив формировался динамически. Следующий пример является более сложным и демонстрирует, как создавать в сценарии статические массивы. Ниже показан входной файл grade_student.txt, включающий информацию об учениках нашей секции каратистов. Записи файла содержат два поля: первое — название пояса, которым владеет ученик, второе — категория ученика (взрослый, юниор). Разделителем полей служит символ '#'.
$ cat grade_student.txt
Vellow#Junior
Orange#Senior
Yellow#Junior
Purple#Junior
Brown-2#Junior
White#Senior
Drange#Senior
Red#Junior
Brown-2#Senior
Yellow#Senior
Red#Junior
Blue#Senior
Green#Senior
Purple#Junior
White#Junior .
Наша задача заключается в том, чтобы прочитать файл и получить следующие сведения:
1. Сколько учеников имеют желтый, оранжевый и красный пояса?
2. Сколько взрослых и детей посещают секцию? Рассмотрим такой сценарий:
$ cat belts.awk
#!/bin/awk -f
#Имя файла: belts.awk
#Командная строка: belts.awk grade_student.txt
#Подсчет числа учеников, имеющих желтый, оранжевый и красный пояса,
#а также количества взрослых и юных членов секции.
# Задание разделителя и создание массивов.
BEGIN (
FS="#"
# Создание массива, индексами которого являются
#названия поясов. belt["Yellow"] belt["Orange"] belt["Red"]
#Создание массива, индексами которого являются
#названия категорий учеников. student["Junior"]
student["Senior"]
}
#Если значение первого поля совпадает с индексом массива belt,
#содержимое соответствующего элемента массива увеличивается на единицу. {for(colour in belt)
{if ($1==colour)
belt[colour]++ ) }
# Если значение второго поля совпадает с индексом массива student,
# содержимое соответствующего элемента массива увеличивается на единицу, { for (senior_or_junior in student) { if ($2==senior_or_junior)
student [senior_or_junior] ++
) }
# Вывод полученных результатов
END {
for (colour in belt)
print "The club has", belt[colour], colour, "belts" for(senior_or_junior in student)
print "The club has", 'student[senior_or_junior], \ senior_or_junior, "students" }
В процедурной части шаблона begin в переменную FS записывается символ '#" -pазделитель полей во входном файле. Затем создаются два массива, belt и student, индексами которых являются соответственно названия поясов и названия категорий учеников. Оба массива остаются неинициализированными, их тип не определен.
В первом цикле for значение первого поля каждой записи входного файла сравнивается с названием индекса массива belt (индекс равен "Yellow", "Orange" или "Red"). Если обнаруживается совпадение, выполняется приращение элемента, хранящегося в массиве по этому индексу. Поскольку операция ++ (инкремент) определена для целочисленных значений, утилита awk считает, что массив целочисленный, и инициализирует его элементы значением 0.
Во втором цикле for значение второго поля сравнивается с названием индекса массива student (индекс равен "Junior" или "Senior"). Результат операции вычисляется так же, как и в первом цикле.
В процедурной части шаблона end осуществляется вывод итоговых результатов.
$ belts.awk grade_student.txt
The club has 2 Red belts
The club has 2 Orange belts
The club has 3 Yellow belts
The club has 7 Senior students
The club has 8 Junior students
9.3. Заключение
Язык программирования awk может показаться сложным для изучения, но если осваивать его на примерах употребления отдельных команд и небольших сценариев, то процесс обучения не будет слишком трудным. В данной главе мы изучили основы awk, не углубляясь в детали, но, тем не менее, получили необходимый минимум сведений, относящихся к этому языку. Утилита awk является важным инструментом shell–программирования, и чтобы применять ее, вам не обязательно быть экспертом по языку awk.
ГЛАВА 10
Работа с редактором sed
Редактор sed относится к текстовым редакторам потокового типа и не является интерактивной программой. Он предназначен для обработки текстовых данных, поступающих из файла или стандартного входного потока. Отличительной особенностью редактора sed является то, что он позволяет модифицировать файлы в фоновом режиме. Задача пользователя сводится к тому, чтобы задать последовательность команд редактирования, а всю остальную работу выполнит сам редактор. Кроме того, sed допускает внесение всех изменений за один проход, а это превращает его в достаточно эффективный и, что важнее всего, быстродействующий инструмент редактирования текста.