UNIX — универсальная среда программирования - Керниган Брайан Уилсон Страница 53
- Категория: Компьютеры и Интернет / Интернет
- Автор: Керниган Брайан Уилсон
- Страниц: 187
- Добавлено: 2020-09-17 00:34:49
UNIX — универсальная среда программирования - Керниган Брайан Уилсон краткое содержание
Прочтите описание перед тем, как прочитать онлайн книгу «UNIX — универсальная среда программирования - Керниган Брайан Уилсон» бесплатно полную версию:UNIX — универсальная среда программирования - Керниган Брайан Уилсон читать онлайн бесплатно
$ cat double
awk '
FILENAME != prevfile { # new file
NR = 1 # reset line number
prevfile = FILENAME
}
NF > 0 {
if ($1 == lastword)
printf "double %s, file %s, line %d\n" ,$1, FILENAME, NR
for (i = 2; i <= NF; i++)
if ($i == $(i-1))
printf "double %s, file %s, line %d\n", $i, FILENAME, NR
if (NF > 0)
lastword = $NF
}' $*
*
$
Операция ++ означает автоувеличение операнда, а операция -- — его автоуменьшение.
Встроенная переменная FILENAME хранит имя текущего входного файла. Поскольку в переменной NR подсчитывается число строк с начала входного потока, мы изменяем ее значение всякий раз при изменении имени файла, чтобы точно указать строку с двойником.
Оператор if — такой же, как в языке Си:
if (условие)
оператор1
else
оператор2
Если условие верно, то выполняется оператор1; если оно ложно и если альтернативная часть присутствует, то выполняется оператор2. Альтернативная часть не обязательна.
Цикл for аналогичен таковому в языке Си, но отличается от цикла в языке shell:
for (выражение1; условие; выражение2)
оператор
Цикл for идентичен приведенному ниже оператору, который также допустим в программе awk:
Выражение1 while (условие) {
оператор
выражение2
}
Например, конструкция
for (i=2; i <= NF; i++)
является циклом с i, принимающим значения 2, 3 и т.д., включая число полей NF.
Оператор break вызывает немедленный выход из цикла while или for; оператор continue инициирует переход к следующему шагу цикла (к условию в операторе while или к выражению2 в операторе for). Оператор next вызывает чтение следующей входной строки и сопоставление ее с шаблонами с начала программы awk, а оператор exit — немедленный переход на действия, определенные в шаблоне END.
МассивыКак и в большинстве языков программирования, в awk есть массивы. В качестве простого примера приведем программу awk, в которой каждая входная строка заносится в отдельный элемент массива, индексируемого номером строки, а затем они печатаются в обратном порядке:
$ cat backwards
# backwards: print input in backward line order
awk ' { line[NR] = $0 }
END { for (i = NR; i > 0; i--) print line[i] } ' $*
$
Заметьте, что подобно переменным, массивы не нужно описывать; размер массива ограничен только объемом памяти, доступным на вашей машине. Конечно, если очень большой файл заносится в массив, в конце концов, это может привести к исчерпанию ресурсов памяти. Для печати конца большого файла в обратном порядке следует обратиться за помощью к команде tail:
$ tail -5 /usr/dict/web2 | backwards
zymurgy
zymotically
zymotic
zymosthenic
zymosis
$
Команда tail использует возможности файловой системы — операцию "поиск" (seeking), позволяющую перейти к концу файла без чтения всей предшествующей информации. Подробнее эта операция будет рассмотрена при обсуждении функции lseek в гл. 7. (В нашей команде tail есть флаг -r, который определяет печать строк в обратном порядке, заменяя команду backwards).
При обычной обработке входная строка разбивается на поля. Эту операцию можно выполнить с помощью встроенной функции split над любой строкой:
n = split(s, arr, sep)
Строка s разбивается на поля, записываемые в элементы массива arr от 1 до n. Используется символ разделения полей sep, если он задан; в противном случае применяется текущее значение переменной FS. Например, обращение split($0, а, ":") разбивает входную строку на столбцы, что подходит для обработки файла /etc/passwd, поэтому обращение split("9/29/83", date, "/") разбивает дату по символам дробной черты.
$ sed 1q /etc/passwd | awk '{split($0, a, ":"); print a[1]}'
root
$ echo 9/29/83 | awk '{split($0, date, "/"); print date[3]}'
83
$
В табл. 4.5 перечислены встроенные функции awk.
cos(expr) Косинус expr exp(expr) Возведение в степень expr getline() Чтение следующей входной строки; возвращает 0 в случае конца файла, в противном случае 1 index(s1, s2) Положение строки s2 в s1; возвращает 0, если строка не входит int(expr) Целая часть expr; округляет по минимуму length(s) Длина строки s log(expr) Натуральный логарифм expr sin(expr) Синус expr split(s, a, c) Разбиение s на а[1] ... a[n] по символу c; возвращает n sprintf(fmt, ...) Форматирование в соответствии со спецификацией fmt substr(s,m,n) Подстрока в n символов строки s, начинающаяся с индекса mЖалоба
Напишите нам, и мы в срочном порядке примем меры.