Таблица 8.1. Основные классы символов и эквивалентные им регулярные выражения
Класс
Эквивалентное регулярное выражение
[:upper:]
[A‑Z]
[:lower:]
[a‑z]
[:digit:]
[0-9]
[:alnum:]
[0-9a‑zA‑Z]
[:space:]
символы пробела
[:alpha:]
[a‑zA‑Z]
Отличие классов от эквивалентных регулярных выражений, приведенных в табл. 8.1, состоит в том, что класс включает не только символы английского алфавита из стандартной таблицы ASCII–кодов, но также символы того национального языка, который установлен в данной конкретной системе.
Рассмотрим несколько примеров на базе нашего файла data.f. Предположим, требуется найти все коды заказов, которые содержат цифру 5, сопровождаемую по крайней мере двумя буквами в верхнем регистре:
$ grep '5[[:upper:]][[:upper]] ' data.f
483 Sept 5АР1996 USP 65.00 LVX2C 189
483 may 5РА1998 USP 37.00 KVM9D 644
Вот как осуществляется поиск всех кодов товара, которые оканчиваются буквой 'P' или 'D':
$ grep '[[:upper:]][[:upper:]][PD]' data.f
483 Sept 5AP1996 USP 65.00 LVX2C 159
219 dec 2CC1999 CAD 23.00 PLV2C 68
484 nov 7PL1996 CAD 49.00 PLV2C 234
483 may 5PA1998 USP 37.00 KVM9D 644
216 sept 3ZL1998 USP 86.00 KVM9E 234
8.4. Дополнительные примеры использования команды grep
В следующих примерах команда grep принимает по каналу результаты работы других команд, фильтруя их надлежащим образом.
8.4.1. Фильтрация списка файлов
Если требуется извлечь из списка файлов текущего каталога только подкаталоги, воспользуйтесь следующей командой:
$ 1s -l | grep '^d'
Представленная ниже команда выбирает из списка файлов текущего каталога, только те записи, которые относятся к файлам, а не к подкаталогам:
S ls -l | grep '^[d]'
Выполнить поиск каталогов, в которых установлены биты поиска для группы и других пользователей, позволяет такая команда:
$ ls -1 | grep '^d.....x..x'
8.4.2. Подавление вывода сообщений об ошибках
Допустим, вы хотите найти запись пользователя louise в системном файле паролей:
$ grep louise /etc/passwd
louise:lxAL6GW9G.ZyY:501:501:Accounts Sect1С:/home/accts/louise:/bin/sh
He исключена возможность, что вы забудете, как называется этот файл. В таком случае воспользуйтесь следующей командой:
$ grep louise /etc/password
grep: /etc/password: No such file or directory
Команда grep выводит сообщение об ошибке, в которой говорится о том, что указанного файла не существует. Можно попробовать провести поиск во всех файлах каталога /etc:
$ grep louise /etc/*
Однако в результате будут выведены многочисленные сообщения об ошибках, гласящие, что к определенным файлам доступ запрещен, а некоторые элементы каталога являются подкаталогами и поиск в них не ведется.
В подобной ситуации можно воспользоваться опцией -s, которая подавляет вывод сообщений об ошибках:
$ grep -a louise /etc/*
Если ваша версия команды grep не поддерживает данную опцию, воспользуйтесь следующей командой:
$ grep louise /etc/* 2> /dev/null
Эта команда направляет поток ошибок (2>) в системную корзину (устройство /dev/null). На жаргоне системных администраторов это устройство называется битодробилкой.
8.4.3. Фильтрация списка процессов
Совместное применение команд grep и ps а позволяет выяснить, выполняется ли в системе некоторый процесс. Опция а команды ps задает вывод списка всех процессов, включая процессы других пользователей. Например, следующая команда проверяет, выполняется ли в данный момент процесс named:
$ ps а | grep named
211 ? S 4.56 named
303 3 s 0.00 grep named
Выводимый результат включает также саму команду grep, поскольку она создает процесс, выполняющий фильтрацию текста в канале, и команда ps распознает этот процесс. Чтобы исключить команду grep из результата, задайте дополнительную команду grep с опцией -v:
$ ps ах | grep named | grep -v "grep"
211 ? S 4.56 named
8.5. Команда egrep
Команда egrep (extended grep( воспринимает как базовые, так и расширенные регулярные выражения. Одной из привлекательных ее особенностей является возможность сохранения шаблонов поиска в файле. Подключается этот файл с помощью опции -f. Рассмотрим пример:
$ cat grepstrings
484
47
$ egrep -f grepstrings data.f
В этом случае в файле data.f осуществляется поиск записей, которые содержат последовательность символов "484" или "47". Создание файла шаблонов удобно в том случае, когда шаблонов очень много и вводить их в командной строке затруднительно. Если шаблонов немного, воспользуйтесь метасимволом '|', который позволяет сделать выбор между несколькими шаблонами. Например, следующая команда ищет в файле data.f записи, содержащие последовательность символов "3ZL" или "2СС":
$ egrep '3ZL|2CC' data.f
47 Oct 3ZL1998 LPSX 43 .00 KVM9D Ы2
219 dec 2СС1999 CAD 23 .00 PLV2C 68
216 sept 3ZL1998 USP 86 .00 KVM9E 234
Метасимвол '|' можно применять более одного раза. Например, чтобы узнать, зарегистрированы ли в системе пользователи louise, matty и pauline, выполните команду who и направьте результаты ее работы команде egrep:
$ who | egrep 'louise|matty|pauline'
louise pty8
mattу tty02
pauline pty2
Круглые скобки позволяют представить выражение с несколькими шаблонами как один шаблон. Так, с помощью представленной ниже команды можно найти в текущем каталоге файлы, в которых встречаются слова из ряда "shutdown", "shutdowns", "reboot" и "reboots":
$ egrep '[shutdown|reboot]s?' *
8.6. Заключение
В настоящей главе продемонстрированы лишь некоторые из многочисленных возможностей команды grep, которая является универсальным инструментом фильтрации, очень популярным среди пользователей UNIX и Linux. Существует несколько ее разновидностей, которые в некоторых системах заменены единой GNU–командой grep. Как будет показано далее в этой книге, команда grep также является важным инструментом shell–программирования, используемым в связке с другими утилитами UNIX.
ГЛАВА 9
Утилита awк
При форматировании отчетов и извлечении информации из больших текстовых файлов неоценимую помощь оказывает утилита awk, которая обладает мощными средствами обработки текста. Как показывает опыт, среди всех инструментов фильтрации, имеющихся в интерпретаторе shell, труднее всего освоить работу именно с awk. Причина этого явления не ясна. Может быть, дело в синтаксисе утилиты или не совсем понятных сообщениях об ошибках, таких как bailing out и awk: cmd. line:. Подобные сообщения довольно часто встречаются при программировании на языке awk. Именно так — язык awk, поскольку это совершенно самостоятельный язык программирования. Возможно, изучать его нелегко, но его совместное применение с другими инструментальными средствами, такими как команда grep и редактор sed, позволяет значительно упростить программирование в интерпретаторе shell.
В главе не делается попытка изучить все возможности утилиты awk и не рассматриваются методы написания сложных сценариев на языке awk, так как для этого потребовалась бы отдельная книга. Мы научимся создавать эффективные однострочные команды и небольшие сценарии, выполняющие фильтрацию текстовых файлов и строк. Итак, в этой главе рассматриваются следующие темы: