обобщаются и шаблоны, и действия. Команда sed
, производная от ed
, выполняет "программу", состоящую из команд редактирования. Она пропускает данные из файлов через эту программу, выполняя для каждой строки команды из программы. Команда awk
не так удобна, как sed,
для манипуляций с текстом, но в ней предусмотрены арифметические операции, переменные, встроенные функции и язык программирования, схожий с Си. В данной главе не приводится полное описание обеих программ; оно есть в т. 2B справочного руководства по UNIX.4.1 Семейство программ grep
В гл. 1 мы кратко упомянули о команде
grep
, а затем использовали ее в примерах. Конструкция$ grep шаблон имена_файлов
проводит поиск в поименованных файлах или в стандартном входном потоке и выводит на печать каждую строку, в которую входит шаблон. Команда
grep
неоценима для поиска переменных в программах и слов в документах, а также для выбора части выходного потока программы:$ grep -n variable *.[гл]
Поиск variable в тексте на Си$ grep From $MAIL
Печать заголовков сообщений из почтовойпосылки
$ grep From $MAIL | grep -v mary
Заголовки, которые получены не отадресата mary
$ grep -y mary $HOME/lib/phone-book
Поиск номера mary$ who | grep mary
Выяснить, работает ли mary в системе$ ls | grep -v temp
Имена файлов, не содержащих tempФлаг
-n
инициирует вывод номеров строк, флаг -v
меняет на противоположное значение условия, а флаг -y
допускает сопоставление строчных букв из шаблона с прописными буквами из файла (но прописные буквы все-таки могут сопоставляться только с прописными).Во всех рассматривавшихся до сих пор примерах проводился поиск обычных строк из букв и чисел. Но команда
grep
может искать и более сложные шаблоны: она интерпретирует выражения согласно простому языку для описания строк. С технической точки зрения шаблон представляет в некоторой степени ограниченную форму спецификаций строк, называемую регулярным выражением. Команда интерпретирует такие же регулярные выражения, как и редактор ed
. На самом деле, эта команда была создана (за один вечер) прямым редактированием ed
.Регулярные выражения характеризуются тем, что ряду символов, таким, как
*
и т.п., приписывается специальное значение, используемое интерпретатором. Есть еще несколько метасимволов, но, к сожалению, с различными значениями. В табл. 4.1 показаны все метасимволы регулярных выражений, и мы кратко их здесь рассмотрим.с
Любой неспециальный символ c соответствует самому себе \c
Указание убрать любое специальное значение символа c
^
Начало строки $
Конец строки .
Любой одиночный символ [...]
Любой символ из ...;
допустимы диапазоны типа a-z
[^...]
Любой символ не из ...
; допустимы диапазоны \n
Строка, соответствующая n-му выражению \(...\)
(только для grep
) r*
Нуль или более вхождений r
r+
Одно или более вхождений r
(только для egrep) r?
Нуль или одно вхождение r
(только для egrep) r1r2
За r1
следует r2
r1|r2
r1
или r2
(только для egrep)\(r\)
Помеченное регулярное выражение r
(только для grep
); может быть вложенным (r)
Регулярное выражение r
(только для
grep); может быть вложенным Никакое регулярное выражение не соответствует концу строки
Таблица 4.1: Регулярные выражения grep
и egrep
(в порядке убывания приоритета)
Метасимволы
^
и $
привязывают шаблон к началу (^
) или концу ($
) строки. Например,$ grep From $MAIL
ищет строки, содержащие
From
в вашей почтовой посылке, но$ grep '^From' $MAIL
выдает строки, начинающиеся с
From
, которые, вероятнее всего, будут заглавными строками сообщений. Метасимволы регулярных выражений пересекаются с метасимволами интерпретатора, поэтому всегда имеет смысл заключать шаблоны команды grep
в апострофы.Команда
grep
допускает классы символов, подобные тем, что используются интерпретатором: так, [a-z]
задает любую строчную букву. Но есть и различия — если класс символов команды grep
начинается с символа слабого ударения то шаблон задает любой символ, кроме входящих в данный класс. Значит, [^0-9]
задает любой символ, кроме цифры. Как и в интерпретаторе, обратная дробная черта экранирует символы ]
и -
в классе символов, но команды grep
и ed
требуют, чтобы эти символы использовались там, где их значение недвусмысленно. Например, шаблон [][-]
задает открывающую или закрывающую квадратную скобку либо знак минус.Точка
'.'
эквивалентна '?'
в интерпретаторе: она задает любой символ. (Точка, по всей видимости, есть символ, назначение которого различно для разных программ.) Ниже приводятся два примера:$ ls -l | grep '^d'
Список имен вложенных каталогов$ ls -l | grep '^.......rw'
Список файлов, доступных всем для чтения и записиСимвол
'^'
и семь точек задают любые семь символов в начале строки; в случае применения к выходному потоку команды ls -l
задается любая строка права доступа.Операция "повторитель" (
'*'
) применима в выражении к предваряющему ее символу или метасимволу (включая класс символов), и вместе они обозначают любое число вхождений символа или метасимвола. Например, x*
задает последовательность букв x
произвольной длины, [a-zA-Z]*
— любую строку букв, .*
— все до конца строки, а .*x
— все до последнего символа x
в строке включительно. Необходимо отметить несколько важных моментов, связанных с повторителем. Во-первых, повторитель действует только на один символ, поэтому xy*
соответствует x
, за которым идут yy...
, но не последовательности типа xyxyxy
. Во-вторых, любое число включает нуль, поэтому если вы хотите, чтобы символ присутствовал, в шаблоне его нужно повторить. Например, правильным выражением, задающим строку букв, является такое: [a-zA-Z][a-zA-Z]*
(буква, за которой следует нуль или более букв). Регулярное выражение .*
соответствует — *
, т.е. метасимволу интерпретатора, используемому для имен файлов.Ни одно регулярное выражение команды
grep
не соответствует символу перевода строки; выражения сопоставляются с каждой строкой в отдельности. Регулярные выражения делают команду grep
простым языком программирования. Вспомните, что второе поле файла паролей содержит зашифрованный пароль. Приведенная ниже команда проводит поиск пользователей, не имеющих пароля:$ grep '^[^:]*::' /etc/passwd
Шаблон расшифровывается так: начало строки, любое число символов, отличных от двоеточия, два двоеточия.
Команда
grep
— старейшая в семействе программ, к которому относятся команды fgrep
и egrep
. В основном их действие одинаково, но