Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2557 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 6:

Средства обработки структурированных данных

Перечислим специальные переменные awk.

ARGC

Число элементов в массиве ARGV.

ARGV

Массив аргументов командной строки awk, исключая опции и программы.

CONVFMT

Формат для преобразования чисел в цепочки символов (кроме операторов вывода, где используется переменная   OFMT, см. далее). По умолчанию - %.6g.

ENVIRON

Массив, представляющий окружение. Индексами служат цепочки символов, совпадающих с именами переменных окружения.

FILENAME

Имя файла, из которого в данный момент производится ввод.

FNR

Порядковый номер текущей записи в текущем исходном файле.

FS

РРВ - разделитель полей во входных данных, по умолчанию - пробел.

NF

Количество полей в текущей записи.

NR

Порядковый номер текущей записи, считая от начала обработки исходных данных.

OFMT

Формат вывода чисел, по умолчанию %.6g.

OFS

Разделитель полей при выводе, по умолчанию - пробел.

ORS

Разделитель записей при выводе, по умолчанию - перевод строки.

RLENGTH

Длина успешно сопоставленной функцией match() цепочки символов.

RS

Первым символом цепочки, представляющей собой значение переменной   RS, является разделитель исходных записей (по умолчанию - перевод строки). Если значение RS пусто, между записями может располагаться несколько пустых строк.

RSTART

Начальная позиция успешно сопоставленной функцией match()   цепочки символов (считая от 1).

SUBSEP

Цепочка символов - разделитель индексов многомерных массивов; подразумеваемое значение зависит от реализации.

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

{ s += $1 } END { print "Сумма:", s, 
" Среднее арифметическое:", s/NR }
Листинг 6.26. Пример awk-программы, оперирующей с числами.

Командная строка из листинга 6.27, служит для вывода тех строк файла f1.txt, у которых первое поле не совпадает с первым полем предыдущей строки.

awk '$1 != prev { print; prev = $1 }' f1.txt
Листинг 6.27. Пример awk-программы, заданной в командной строке.

Чтобы распечатать файл f2.txt, вставляя после слова "Page" номера страниц (начиная с первой), можно воспользоваться awk-программой (предполагается, что она помещена в файл prog.awk ) и командной строкой, представленными, соответственно, в листингах 6.28 и 6.29.

/Page/ { $2 = n++ } { print }
Листинг 6.28. Пример awk-программы, использующей шаблоны.
awk -f prog.awk -v 'n=1' f2.txt
Листинг 6.29. Пример вызова awk-программы, использующей шаблоны.

Программа, показанная в листинге 6.30, выводит поля входных записей, по одному на строке.

{ for (i = NF; i > 0; --i) print $i }
Листинг 6.30. Пример awk-программы, использующей оператор цикла.

Промоделировать работу утилиты echo можно с помощью awk-программы (см. листинг 6.31).

BEGIN {
   for (i = 1; i < ARGC; ++i)
   printf ("%s%s", ARGV [i], 
           i == ARGC - 1 ? "\n" : " ")
}
Листинг 6.31. Пример awk-программы, использующей оператор цикла и специальные переменные awk.

Следующая awk-программа (см. листинг 6.32) позволяет разложить список поиска, хранящийся в переменной окружения PATH, по элементам массива.

BEGIN {
   n = split (ENVIRON ["PATH"], path, ":")
   for (i = 1; i <= n; ++i)
      print path [i]
}
Листинг 6.32. Пример awk-программы, использующей встроенную функцию split().

В листинге 6.33 приведен фрагмент командного файла, выполняемого при выключении системы. Здесь можно обратить внимание на разные виды экранирования. (Третье поле в выдаче mount - это точка монтирования.)

# Перемонтируем на чтение все, что еще остается смонтированным.
mount | awk '/( \/ |^\/dev\/root)/ { print $3 }' | while read line; do
   mount -n -o ro,remount $line
done
Листинг 6.33. Пример использования утилиты awk в системном командном файле.

Отметим, что в POSIX-2001 стандартизована весьма развитая версия awk, входной язык которой приближен к языку C.

Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?