UNIX — универсальная среда программирования - Керниган Брайан Уилсон Страница 50
- Категория: Компьютеры и Интернет / Интернет
- Автор: Керниган Брайан Уилсон
- Страниц: 187
- Добавлено: 2020-09-17 00:34:49
UNIX — универсальная среда программирования - Керниган Брайан Уилсон краткое содержание
Прочтите описание перед тем, как прочитать онлайн книгу «UNIX — универсальная среда программирования - Керниган Брайан Уилсон» бесплатно полную версию:UNIX — универсальная среда программирования - Керниган Брайан Уилсон читать онлайн бесплатно
4.4 Язык awk поиска и обработки шаблонов
Некоторые ограничения sed преодолены в программе awk. Принцип работы этой программы сходен с принципом работы программы sed, но синтаксически она ближе к языку программирования Си, чем к текстовому редактору. Способ задания команды такой же, как и для sed:
$ awk 'программа' имена_файлов...
но программа другая:
шаблон {действие}
шаблон {действие}
...
Программа awk читает входной поток по одной строке из указанных файлов. Строки сопоставляются с шаблонами по порядку; для каждого шаблона, соответствующего строке, выполняется необходимое действие. Как и в редакторе sed, входные файлы здесь не изменяются.
Шаблоны могут быть регулярными выражениями в sed или более сложными условиями, напоминающими язык Си. Приведем простой пример (такого же результата можно добиться с помощью команды egrep):
$ awk '/регулярное_выражение/ {print}' имена_файлов...
Печатается каждая строка, соответствующая регулярному выражению.
Шаблоны или действия могут отсутствовать. Если отсутствует действие, то по умолчанию печатаются строки, соответствующие шаблону, поэтому команда
$ awk '/регулярное_выражение/' имена_файлов...
эквивалентна предыдущей. Наоборот, если отсутствует шаблон, то действие выполняется для каждой входной строки. Следовательно, команда
$ awk '{print}' имена_файлов...
дает те же результаты, что и команда cat, хотя действует медленнее.
Теперь перейдем к более интересным примерам, но прежде сделаем одно замечание. Как и в случае sed, программу команды awk можно получать из файла:
$ awk -f кмд файл имена_файлов...
Поля. В программе awk каждая входная строка автоматически разбивается на поля, т.е. последовательности символов без пробелов, разделенные пробелами и символами табуляции. По этому определению выходной поток команды who имеет пять полей:
$ who
you tty2 sep 29 11:53
jim tty4 sep 29 11:27
$
Поля обозначаются как $1, $2, …, $NF, где NF — переменная, значение которой установлено равным числу полей. В нашем случае NF=5 для обеих строк. (Учтите разницу между NF, числом полей и $NF — последним полем строки. В отличие от интерпретатора в программе awk только номера полей начинаются с $; переменные не имеют такого префикса.) Например, следующая команда выдаст поле "размер файла" из результата выполнения команды du -а
$ du -a | awk '{print $2}'
а для печати имен пользователей, работающих в системе, и времени входа нужно задать:
$ who awk '{print $1, $5}'
you 11:53
jim 11:27 $
Для печати имени и времени входа в систему, упорядоченных по времени, зададим:
$ who awk '{print $5, $1}' | sort
11:27 jim
11:53 you
$
Это альтернативные решения примеров, приведенных выше в данной главе, в которых использовалась команда sed. Хотя с программой awk проще работать в подобных случаях, она обычно выполняется медленнее как в начальной фазе, так и при большом входном потоке.
Обычно предполагается, что поля разделяются произвольным числом пробелов и символов табуляций, но можно определить в качестве разделителя любой одиночный символ. Один из способов состоит в задании в командной строке флага -F (здесь прописная буква). Например, поля в файле паролей /etc/passwd разделяются двоеточиями:
$ sed 3q /etc/passwd
root:3D.fHR5KoB.3s:0:1:S.User:/:
ken:y.68wdl.ijayz:6:1:K.Thompson:/usr/ken:
dmr:z4u3dJWbg7wCk:7:1:D.M.Ritchie:/usr/dmr:
$
Для печати имен пользователей, образующих первое поле, можно задать:
$ sed 3q /etc/passwd | awk -F : '{print $1}'
root
ken
dmr
Обработка пробелов и символов табуляции здесь особая. По умолчанию и пробелы, и символы табуляции служат разделителями, а разделители в начале строки отбрасываются. Однако если в качестве разделителя определен не пробел, то разделители в начале строки учитываются при определении полей. В частности, если используется символ табуляции, то пробелы не являются символами разделителями, пробелы в начале строки вводят в поле, и каждый символ табуляции определяет поле.
ПечатьВ программе awk, помимо числа входных полей, доступна и другая интересная информация. Встроенная переменная NR хранит номер текущей входной "записи", т.е. строки. Поэтому для вставки номера строки перед строкой входного потока достаточно задать:
$ awk '{print NR, $0}'
Поле $0 обозначает всю входную строку без изменений. В операторе print фрагменты, отделяемые запятой, печатаются через символы разделения полей выходного потока, которые по умолчанию служат пробелами.
Формат печати оператора print обычно является приемлемым. При несоответствующем формате используйте оператор printf, обеспечивающий полный контроль над выходным потоком. Например, для печати номеров строк в поле размером в четыре цифры можно задать такую команду:
$ awk '{printf "%4d %s\n", NR, $0}'
Выражение %4 задает десятичное целое число (NR) в поле размером в четыре цифры, %S — строка символов ($0), \n — символ перевода строки, который нужен потому, что оператор printf не выдает автоматически пробелы или символы перевода строк. Оператор printf сходен с аналогичной Си функцией (см. справочное руководство по printf(3)).
Жалоба
Напишите нам, и мы в срочном порядке примем меры.