Руководство пользователя для GNU Awk
16. Практические awk-программы
16.1 Переизобретение колеса для забавы и пользы
16.1.7 Подсчет объектов
Утилита wc (word count) подсчитывает количества строк, слов и символов в одном или более входных файлов. Она используется так:
wc [-lwc] [ files ... ]
Если в командной строке файлы не указаны, wc читает свой стандартный ввод. Если указано несколько файлов, будут напечатаны суммарные счетчики для всех файлов. Параметры и их смысл следующие:
-l Только подсчет строк
-w Только подсчет слов. "слова" есть
связные последовательности символов,
не содержащая символов whitespace, разделенные
пробелами и/или символами tab.
К счастью, это нормальный способ для awk разделения
полей в входных данных.
-c Только подсчет символов.
Реализация wc средствами awk особенно элегантна, поскольку awk сама делает большую часть работы; она разделяет строки на слова (т.е. поля) и считает их, подсчитывает строки( т.е. записи) и может легко сообщать нам длину строк. Эта версия использует библиотечную функцию getopt (см. раздел 15.10 [Обработка параметров командной строки], стр. 186), и функции переключения файлов (см. раздел 15.9 [Слежение за границами файлов с данными], стр. 185). Эта версия имеет одно важное отличие от традиционных версий wc. Наша версия постоянно печатает счетчики в порядке: строки, слова, символы. Традиционные версии запоминают порядок параметров `-l', `-w' и `-c' в командной строке и печатают счетчики в этом порядке.
Правило BEGIN обрабатывает аргументы. Переменная print.total будет true, если в командной строке указано более одного файла.
# wc.awk --- счет строк, слов, символов
# Arnold Robbins, arnold@gnu.org, Public Domain # May 1993
# Параметры:
# -l счет только строк
# -w счет только слов
# -c счет только символов
# #По умолчанию подсчет строк, слов и символов
BEGIN -
# Побуждаем getopt печатать сообщение
# о неверных параметров. Мы игнорируем их если
((c = getopt(ARGC, ARGV, "lwc")) != -1) -
if (c == "l")
do.lines = 1 else if (c == "w")
do.words = 1 else if (c == "c")
do.chars = 1 "" for (i = 1; i ! Optind; i++)
ARGV[i] = ""
# если параметров нет, делать все
if (! do.lines && ! do.words && ! do.chars)
do.lines = do.words = do.chars = 1
print.total = (ARGC - i ? 2) ""
Функция beginfile проста; она просто сбрасывает счетчики строк, слов и символов на 0 и запоминает имя текущего файла в fname. Функция endfile добавляет значения текущего файла к соответствующим суммам для строк, слов и символов. Затем печатает эти данные для файла, который был только что прочтен. Она оставляет для beginfile сброс счетчиков для следующего файла с данными.
function beginfile(file) -
chars = lines = words = 0 fname = FILENAME ""
function endfile(file) -
tchars += chars tlines += lines twords += words if (do.lines)
printf ""t%d", lines
if (do.words)
printf ""t%d", words if (do.chars)
printf ""t%d", chars printf ""t%s"n", fname ""
Имеется одно правило, которое выполняется для каждой строки. Оно добавляет длину строки к переменной chars. Оно должно добавлять 1, поскольку символ newline, разделяющий записи (значение RS), не входит в состав строки. Переменная lines увеличивается для каждой прочтенной записи, а words увеличивается на значение NF, количество "слов" в этой строке.*1*
Наконец, правило END просто печатает суммы по всем файлам.
# делать для каждой строки
-
chars += length($0) + 1 # get newline lines++ words += NF ""
END -
if (print.total) -
if (do.lines)
printf ""t%d", tlines if (do.words)
printf ""t%d", twords if (do.chars)
printf ""t%d", tchars print ""ttotal" "" ""
Назад | Вперед
Содержание (общее) | Содержание раздела | Содержание подраздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|