[[email protected] ~]$ for i in {1..10}; do echo "(${RANDOM:0:3}) ${RANDOM:0:3}-${RANDOM:0:4}" >> phonelist.txt; done
Эта команда создаст файл с именем phonelist.txt, содержащий 10 телефонных номеров. Если повторить команду, она добавит в список еще 10 номеров. Также можно изменить число 10 ближе к началу команды, чтобы создать больше или меньше номеров. Однако если заглянуть в файл, можно заметить проблему:
[[email protected] ~]$ cat phonelist.txt
(232) 298-2265
(624) 381-1078
(540) 126-1980
(874) 163-2885
(286) 254-2860
(292) 108-518
(129) 44-1379
(458) 273-1642
(686) 299-8268
(198) 307-2440
Некоторые номера оформлены неправильно, что очень хорошо для целей демонстрации их проверки с помощью grep.
Было бы полезно просканировать файл в поисках недопустимых номеров и вывести их.
[[email protected] ~]$ grep -Ev '^([0-9]{3}) [0-9]{3}-[0-9]{4}$' phonelist.txt
(292) 108-518
(129) 44-1379
[[email protected] ~]$
Здесь мы использовали параметр -v, чтобы обратить сопоставление и вывести только строки, не соответствующие указанному выражению.
Само выражение содержит якорные метасимволы на обоих концах и тем самым гарантирует отсутствие дополнительных символов слева и справа от номера. Кроме того, в отличие от примера, приведенного выше, это выражение также требует обязательного наличия круглых скобок в номере.
Поиск необычных имен файлов с помощью find
Команда find поддерживает проверку, основанную на регулярном выражении. Существует одно важное обстоятельство, которое следует помнить, используя регулярные выражения в командах find и grep. Если grep выводит строку, содержащую совпадение с регулярным выражением, то find требует точного совпадения пути с регулярным выражением. В следующем примере команда find использует регулярное выражение для поиска путей к файлам, содержащим любые символы, не входящие в следующее множество:
[-_./0-9a-zA-Z]
В результате такого поиска можно выявить имена файлов и каталогов, содержащие пробелы и другие, потенциально вредные символы:
[[email protected] ~]$ find . -regex '.*[^-_./0-9a-zA-Z].*'
Из-за требования точного совпадения всего пути мы добавили элемент .* с обоих концов выражения, замещающий любое количество любых символов (в том числе и отсутствие символов). В середине выражения находится инвертированное выражение в квадратных скобках, содержащее множество символов, допустимых в именах файлов и каталогов.
Поиск файлов с помощью locate
Программа locate поддерживает простые (параметр --regexp) и расширенные (параметр --regex) регулярные выражения. Благодаря этому можно выполнять те же операции, что производились выше с файлами dirlist:
[[email protected] ~]$ locate --regex ‚bin/(bz|gz|zip)'
/bin/bzcat
/bin/bzcmp
/bin/bzdiff
/bin/bzegrep
/bin/bzexe
/bin/bzfgrep
/bin/bzgrep
/bin/bzip2
/bin/bzip2recover
/bin/bzless
/bin/bzmore
/bin/gzexe
/bin/gzip
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
Использовав чередование, мы нашли пути, содержащие bin/bz, bin/gz или /bin/zip.
Поиск текста в less и vim
less и vim поддерживают одинаковые способы поиска в тексте. Чтобы выполнить поиск, нажмите клавишу / и введите регулярное выражение. Воспользуемся программой less, чтобы просмотреть содержимое файла phonelist.txt:
[[email protected] ~]$ less phonelist.txt
Затем выполним поиск с применением выражения для проверки:
(232) 298-2265
(624) 381-1078
(540) 126-1980
(874) 163-2885
(286) 254-2860
(292) 108-518
(129) 44-1379
(458) 273-1642
(686) 299-8268
(198) 307-2440
~
~
~
/^([0-9]{3}) [0-9]{3}-[0-9]{4}$
less выделит строки с совпадениями, что позволит сразу увидеть недопустимые номера:
(232) 298-2265
(624) 381-1078
(540) 126-1980
(874) 163-2885
(286) 254-2860
(292) 108-518
(129) 44-1379
(458) 273-1642
(686) 299-8268
(198) 307-2440
~
~
~
(END)
Редактор vim поддерживает только простые регулярные выражения, поэтому выражение для поиска должно выглядеть следующим образом:
/([0-9]{3}) [0-9]{3}-[0-9]{4}
Как видите, выражение практически то же самое; различия обусловлены лишь тем, что многие символы, которые в расширенной версии выражений считаются метасимволами, в простой версии интерпретируются как литералы. Они действуют как метасимволы, только если экранировать их символом обратного слеша. В зависимости от конкретных настроек vim совпадения могут быть выделены или нет. Если совпадения не выделяются, попробуйте в командном режиме выполнить команду :hlsearch, чтобы активировать выделение результатов поиска.
ПРИМЕЧАНИЕ
В разных дистрибутивах vim может поддерживать или не поддерживать подсветку результатов поиска в тексте. В Ubuntu, например, по умолчанию включена сильно упрощенная версия vim. В таких системах необходимо установить боле полную версию vim с помощью диспетчера пакетов.
Заключительное замечание
В этой главе мы рассмотрели несколько примеров использования регулярных выражений. Круг практического применения регулярных выражений можно расширить еще больше, если задействовать их для поиска в других приложениях, поддерживающих такую возможность. Например, с их помощью можно выполнять поиск на страницах справочного руководства:
[[email protected] ~]$ cd /usr/share/man/man1
[[email protected] man1]$ zgrep -El 'regex|regular expression' *.gz
Программа zgrep реализует интерфейс к grep, позволяя читать сжатые файлы. В данном примере выполняется поиск в сжатых файлах первого раздела справочного руководства. Результатом этой команды будет список файлов, содержащих строку regex или regular expression. Как видите, регулярные выражения поддерживаются множеством программ.
Простые регулярные выражения обладают одной интересной особенностью, которую мы пропустили, — обратными ссылками (back references). Они будут рассматриваться в следующей главе.
20. Обработка текста
Все Unix-подобные операционные системы широко используют текстовые файлы для хранения данных разных типов. Этим объясняется такое большое разнообразие инструментов обработки текста. В этой главе мы рассмотрим программы, которые используются для выполнения самых разных манипуляций с текстом. В следующей главе мы продолжим знакомство со средствами обработки текста, уделив больше внимания программам форматирования текста перед печатью и программам, удовлетворяющим другие потребности человека.
В этой главе мы повторно рассмотрим уже знакомые программы и познакомимся с новыми:
• cat — объединяет файлы и выводит их в стандартный вывод.
• sort — сортирует строки из текстовых файлов.
• uniq — сообщает о повторяющихся строках или удаляет их.
• cut — удаляет фрагменты из каждой строки в файлах.
• paste — выполняет слияние строк из файлов.
• join — объединяет строки из двух файлов по общему полю.
• comm — выполняет построчное сравнение двух сортированных файлов.
• diff — выполняет построчное сравнение файлов.
• patch — применяет diff-файл (файл с результатами сравнения командой diff) к оригиналу.
• tr — перекодирует или удаляет символы.
• sed — потоковый редактор для фильтрации и преобразования текста.
• aspell — интерактивная программа проверки орфографии.
Области применения текста
К настоящему моменту мы познакомились с парой текстовых редакторов (nano и vim), рассмотрели несколько конфигурационных файлов и увидели вывод нескольких десятков команд, и все это в текстовом виде. А для чего еще используется текст? Как оказывается, много для чего.
Документы
Многие люди записывают документы в простом текстовом формате. Очевидно, достаточно удобно хранить простые заметки в небольших текстовых файлах, однако и большие документы также можно записывать в простом текстовом формате. Один из популярных подходов состоит в том, чтобы записать большой документ в текстовом формате и затем использовать язык разметки для описания форматирования конечного документа. Многие научные статьи написаны подобным способом, так как системы обработки текста на основе Unix были в числе первых, обеспечивших улучшенную поддержку типографического оформления, так необходимого авторам в технических дисциплинах.
Веб-страницы
Самым популярным в мире форматом электронных документов является, пожалуй, формат веб-страниц. Веб-страницы — это текстовые документы с разметкой HTML (Hypertext Markup Language — язык разметки гипертекста) или XML (Extensible Markup Language — расширяемый язык разметки), описывающей визуальный формат документа.
Электронная почта
Электронная почта является текстовой средой по своей природе. Даже нетекстовые вложения преобразуются в текстовое представление перед передачей. В этом можно убедиться, загрузив электронное письмо и просмотрев его с помощью less. Вы увидите, что письмо начинается с заголовка, описывающего отправителя письма и промежуточные серверы, принимавшие его в процессе доставки, за которым следует тело письма с его содержимым.
Вывод на принтер
В Unix-подобных системах данные выводятся на печать в простом текстовом виде, или, если страница содержит графику, она преобразуется в описание страницы в текстовом формате, известном как PostScript, которое затем посылается программе, генерирующей графические точки для печати на бумаге.