Упражнение 4.5
Измените команды older
и newer
так, чтобы они не включали файл-аргумент в свой выходной поток. Измените их так, чтобы файлы выдавались в обратном порядке.
Упражнение 4.6
С помощью редактора sed
сделайте программу bundle
совершенно надежной. Подсказка: в конструкции "документ здесь" слово, отмечающее конец данных, распознается только в том случае, когда оно совпадает со строкой полностью.
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
Обработка пробелов и символов табуляции здесь особая. По умолчанию и пробелы, и символы табуляции служат разделителями, а разделители в начале строки отбрасываются. Однако если в качестве разделителя определен не пробел, то разделители в начале строки учитываются при определении полей. В частности, если используется символ табуляции, то пробелы не являются символами разделителями, пробелы в начале строки вводят в поле, и каждый символ табуляции определяет поле.
Читать дальше
Конец ознакомительного отрывка
Купить книгу