Red Hat System Administration II 8.2

Сопоставление текста в выводе команды с регулярными выражениями

Задачи

После завершения этого раздела учащиеся смогут:

  • создавать регулярные выражения, позволяющие найти нужные данные;

  • применять регулярные выражения к текстовым файлам с помощью команды grep;

  • искать файлы и данные из конвейера команд с помощью команды grep.

Составление регулярных выражений

Базовые сведения о регулярных выражениях

Регулярные выражения — это механизм сопоставления с шаблоном для поиска определенного содержимого. В командах vim, grep и less могут использоваться регулярные выражения. Языки программирования, такие как Perl, Python и C, могут использовать регулярные выражения для поиска информации, соответствующей шаблону.

Регулярные выражения — это самостоятельный язык, у которого есть свой синтаксис и правила. В этом разделе рассматривается синтаксис создания регулярных выражений, а также показаны некоторые примеры использования регулярных выражений.

Простое регулярное выражение

Самое простое регулярное выражение — это точное совпадение. Точное совпадение имеет место, когда символы в регулярном выражении совпадают по типу и порядку с данными, в которых выполняется поиск.

Предположим, пользователь ищет все вхождения шаблона cat в следующем файле:

cat
dog
concatenate
dogma
category
educated
boondoggle
vindication
chilidog

cat — это точное совпадение с идущими подряд буквами c, a и t, между которыми нет других символов. Если использовать cat в качестве регулярного выражения для поиска по указанному файлу, будут найдены следующие совпадения:

cat
concatenate
category
educated
vindication

Поиск совпадений в начале и конце строки

В предыдущем разделе использовалось регулярное выражение для поиска точного совпадения в файле. Обратите внимание, что регулярное выражение находит искомую фразу, независимо от ее позиции: в начале, в конце или в середине слова или строки. Используйте строковый якорь, чтобы указать место поиска совпадения с помощью регулярного выражения.

Для поиска в начале строки используйте знак крышки (^). Для поиска в конце строки используйте знак доллара ($).

В вышеуказанном файле регулярное выражение ^cat найдет два слова. Регулярное выражение $cat не даст совпадений.

cat
dog
concatenate
dogma
category
educated
boondoggle
vindication
chilidog

Чтобы найти в файле строки, которые оканчиваются словом dog, используйте точное выражение и якорь конца строки, чтобы составить регулярное выражение dog$. Применение dog$ к файлу дает два совпадения:

dog
chilidog

Чтобы найти единственное слово в строке, используйте оба якоря (начала и конца строки). Например, чтобы найти в строке единственное слово cat, используйте выражение ^cat$.

cat dog rabbit
cat
horse cat cow
cat pig

Добавление метасимволов и квантификаторов в регулярные выражения

В регулярных выражениях используется точка (.) для поиска любого одного символа, за исключением символа новой строки. Регулярное выражение c.t выполняет поиск строки, содержащей символ c, за которым следует любой символ, а затем — t. Примеры совпадений: cat, concatenate, vindication, c5t и c$t.

При использовании неограниченного метасимвола вы не можете предсказать, какой символ будет ему соответствовать. Чтобы сопоставить определенные символы, замените неограниченный метасимвол соответствующими символами. Регулярное выражение c[aou]t найдет фразы, начинающиеся с символа с, за которым идет a, o или u, а за ними t.

Квантификаторы — это механизм, часто используемый совместно с метасимволами. Квантификаторы применяются к предыдущему символу в регулярном выражении. Один из наиболее распространенных квантификаторов — символ звездочки (*). При использовании в регулярном выражении такой квантификатор означает совпадение с нулем или большим количеством символов из предыдущего выражения. Вы можете использовать * с выражениями, а не только с символами. Пример: c[aou]*t. Регулярное выражение c.*t соответствует cat, coat, culvert и даже ct (0 символов между c и t). Любые данные, которые начинаются с символа с, затем ноль или больше символов и в конце t.

Другой тип квантификатора указывает количество предыдущих символов, которые должны быть в шаблоне. Пример использования явного квантификатора: 'c.\{2\}t'. Это регулярное выражение совпадает с любым словом, которое начинается с символа с, за которым идут любые два символа, и оканчивается символом t. 'c.\{2\}t' соответствует двум словам в примере ниже:

cat
coat convert
cart covert
cypher

Примечание

Поскольку регулярные выражения часто содержат метасимволы оболочки (например, $, * и {}), рекомендуется заключать выражения в одинарные кавычки. Таким образом, символы будут интерпретированы командой, а не оболочкой.

Примечание

В этом курсе рассматриваются две разные системы разбора текста с метасимволами: сопоставление с шаблоном в командной оболочке (которое также известно как подстановка или развертывание имен файлов) и регулярные выражения. В обеих системах используются одинаковые метасимволы, например звездочка (*), но есть различия в интерпретации метасимволов и применяемых правилах, поэтому необходимо хорошо освоить каждую из этих систем, чтобы правильно их использовать.

Сопоставление с шаблоном ― это метод разбора в командной строке, с помощью которого можно легко указать большое количество имен файлов. Применяется он в основном для представления шаблонов имен файлов в командной строке. Регулярные выражения представляют любую форму и любой шаблон в текстовых строках, независимо от их сложности. Регулярные выражения поддерживаются различными командами обработки текста, такими как grep, sed, awk, python и perl, и многими приложениями с минимальными вариациями в правилах интерпретации выражений, которые зависят от используемой команды.

Таблица 1.1. Регулярные выражения

ОпцияОписание
. Точка (.) соответствует любому отдельному символу.
? Предшествующий элемент является вариативным и будет сопоставлен не более одного раза.
* Предшествующий элемент будет сопоставлен 0 или более раз.
+ Предшествующий элемент будет сопоставлен один или более раз.
{n} Предшествующий элемент сопоставляется ровно n раз.
{n,} Предшествующий элемент сопоставляется n или более раз.
{,m} Предшествующий элемент сопоставляется не более m раз.
{n,m} Предшествующий элемент сопоставляется как минимум n раз, но не более m раз.
[:alnum:] Буквенно-цифровые символы: '[:alpha:]' и '[:digit:]'. В языковом стандарте 'C' и кодировке ASCII это то же самое, что и '[0-9A-Za-z]'.
[:alpha:] Буквенные символы: '[:lower:]' и '[:upper:]'. В языковом стандарте 'C' и кодировке ASCII это то же самое, что и '[A-Za-z]'.
[:blank:] Пустые символы: пробел и табуляция.
[:cntrl:] Управляющие символы. В ASCII это символы с восьмеричными кодами 000–037 и 177 (DEL). В других кодировках это эквивалентные символы, если таковые есть.
[:digit:] Цифры: 0 1 2 3 4 5 6 7 8 9.
[:graph:] Графические символы: '[:alnum:]' и '[:punct:]'.
[:lower:] Буквы нижнего регистра. В языковом стандарте 'C' и кодировке ASCII это буквы a b c d e f g h i j k l m n o p q r s t u v w x y z.
[:print:] Печатные символы: '[:alnum:]', '[:punct:]' и пробел.
[:punct:] Знаки пунктуации. В языковом стандарте 'C' и кодировке ASCII это символы ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ' { | } ~. В других кодировках это эквивалентные символы, если таковые есть.
[:space:] Символ пробела. В языковом стандарте 'C' это табуляция, новая строка, вертикальная табуляция, смена страницы, возврат каретки и пробел.
[:upper:] Буквы верхнего регистра. В языковом стандарте 'C' и кодировке ASCII это буквы A B C D E F G H I J K L M N O P Q R S T U V W X Y Z.
[:xdigit:] Шестнадцатеричные цифры: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f.
\b Сопоставить пустую строку в начале или конце слова.
\B Сопоставить пустую строку, если она не в начале или конце слова.
\< Сопоставить пустую строку в начале слова.
\> Сопоставить пустую строку в конце слова.
\w Сопоставить элементы, составляющие слово. Синоним '[_[:alnum:]]'.
\W Сопоставить элементы, не составляющие слово. Синоним '[^_[:alnum:]]'.
\s Сопоставить пробел. Синоним '[[:space:]]'.
\S Сопоставить не пробел. Синоним '[^[:space:]]'.

Сопоставление регулярных выражений с помощью команды grep

Команда grep, входящая в дистрибутив, использует регулярные выражения для выборки соответствующих данных.

Выборка данных с помощью команды grep

Команда grep предоставляет регулярное выражение и файл, в котором будет выполняться поиск по регулярному выражению.

[user@host ~]$ grep '^computer' /usr/share/dict/words
computer
computerese
computerise
computerite
computerizable
computerization
computerize
computerized
computerizes
computerizing
computerlike
computernik
computers

Примечание

Поскольку регулярные выражения часто содержат метасимволы оболочки (например, $, * и {}), рекомендуется заключать выражения в одинарные кавычки. Таким образом, символы будут интерпретированы командой grep, а не оболочкой.

Команду grep можно использовать вместе с другими командами с помощью оператора конвейера (|). Пример:

[root@host ~]# ps aux | grep chrony
chrony     662  0.0  0.1  29440  2468 ?        S    10:56   0:00 /usr/sbin/chronyd

Опции команды grep

У команды grep есть много полезных опций, которые позволяют указать, как следует использовать указанное регулярное выражение с данными.

Таблица 1.2. Распространенные опции grep

ОпцияФункция
-i Использует указанное регулярное выражение, но без учета регистра.
-v Отображает только те строки, которые не соответствуют регулярному выражению.
-r Выполняет поиск данных, которые соответствуют регулярному выражению, рекурсивно для группы файлов или каталогов.
-A NUMBER Отображает количество (NUMBER) строк после совпадения с регулярным выражением.
-B NUMBER Отображает количество (NUMBER) строк перед совпадением с регулярным выражением.
-e Используя несколько опций -e, можно указать несколько регулярных выражений, разделенных логическим ИЛИ.

У команды grep есть и другие опции. Ознакомиться с ними можно на соответствующей man-странице.

Примеры использования команды grep

В следующих примерах используются различные файлы конфигурации и log-файлы.

По умолчанию в регулярных выражениях учитывается регистр символов. Используйте с командой grep опцию -i для выполнения поиска без учета регистра Следующий пример иллюстрирует поиск по шаблону serverroot.

[user@host ~]$ cat /etc/httpd/conf/httpd.conf
...output omitted...
ServerRoot "/etc/httpd"

#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80
...output omitted...
[user@host ~]$ grep -i serverroot /etc/httpd/conf/httpd.conf
# with "/", the value of ServerRoot is prepended -- so 'log/access_log'
# with ServerRoot set to '/www' will be interpreted by the
# ServerRoot: The top of the directory tree under which the server's
# ServerRoot at a non-local disk, be sure to specify a local disk on the
# same ServerRoot for multiple httpd daemons, you will need to change at
ServerRoot "/etc/httpd"

Если известно, что не надо искать, можно использовать опцию -v. Опция -v отображает только те строки, которые не соответствуют регулярному выражению. В следующем примере возвращаются все строки (независимо от регистра), которые не содержат регулярное выражение server.

[user@host ~]$ cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

172.25.254.254  classroom.example.com classroom
172.25.254.254  content.example.com content
172.25.254.254  materials.example.com materials
172.25.250.254  workstation.lab.example.com workstation
### rht-vm-hosts file listing the entries to be appended to /etc/hosts

172.25.250.10   servera.lab.example.com servera
172.25.250.11   serverb.lab.example.com serverb
172.25.250.254  workstation.lab.example.com workstation
[user@host ~]$ grep -v -i server /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

172.25.254.254  classroom.example.com classroom
172.25.254.254  content.example.com content
172.25.254.254  materials.example.com materials
172.25.250.254  workstation.lab.example.com workstation
### rht-vm-hosts file listing the entries to be appended to /etc/hosts

172.25.250.254  workstation.lab.example.com workstation

Чтобы скрыть строки комментариев в файле, используйте опцию -v. В следующем примере регулярное выражение соответствует всем строкам, которые начинаются с символа # или ; (то есть с типичных символов, которые указывают на начало комментария). Эти строки исключаются из вывода.

[user@host ~]$ cat /etc/ethertypes
#
# Ethernet frame types
#       This file describes some of the various Ethernet
#       protocol types that are used on Ethernet networks.
#
# This list could be found on:
#         http://www.iana.org/assignments/ethernet-numbers
#         http://www.iana.org/assignments/ieee-802-numbers
#
# <name>    <hexnumber> <alias1>...<alias35> #Comment
#
IPv4        0800    ip ip4      # Internet IP (IPv4)
X25     0805
ARP     0806    ether-arp   #
FR_ARP      0808            # Frame Relay ARP        [RFC1701]
...output omitted...
[user@host ~]$ grep -v '^[#;]' /etc/ethertypes
IPv4        0800    ip ip4      # Internet IP (IPv4)
X25     0805
ARP     0806    ether-arp   #
FR_ARP      0808            # Frame Relay ARP        [RFC1701]

Команда grep с опцией -e позволяет выполнять поиск одновременно по нескольким регулярным выражениям. В следующем примере используется комбинация из less и grep для поиска всех вхождений pam_unix, user root и Accepted publickey в log-файле /var/log/secure.

[root@host ~]# cat /var/log/secure | grep -e 'pam_unix' \
-e 'user root' -e 'Accepted publickey' | less
Mar 19 08:04:46 host sshd[6141]: pam_unix(sshd:session): session opened for user root by (uid=0)
Mar 19 08:04:50 host sshd[6144]: Disconnected from user root 172.25.250.254 port 41170
Mar 19 08:04:50 host sshd[6141]: pam_unix(sshd:session): session closed for user root
Mar 19 08:04:53 host sshd[6168]: Accepted publickey for student from 172.25.250.254 port 41172 ssh2: RSA SHA256:M8ikhcEDm2tQ95Z0o7ZvufqEixCFCt+wowZLNzNlBT0

Для поиска текста в файле, открытом с помощью команды vim или less, введите символ косой черты (/) и искомый шаблон. Нажмите Enter, чтобы начать поиск. Нажмите N, чтобы найти следующее совпадение.

[root@host ~]# vim /var/log/boot.log
...output omitted...
[^[[0;32m  OK  ^[[0m] Reached target Initrd Default Target.^M
  Starting dracut pre-pivot and cleanup hook...^M
[^[[0;32m  OK  ^[[0m] Started dracut pre-pivot and cleanup hook.^M
  Starting Cleaning Up and Shutting Down Daemons...^M
  Starting Plymouth switch root service...^M
  Starting Setup Virtual Console...^M
[^[[0;32m  OK  ^[[0m] Stopped target Timers.^M
[^[[0;32m  OK  ^[[0m] Stopped dracut pre-pivot and cleanup hook.^M
[^[[0;32m  OK  ^[[0m] Stopped target Initrd Default Target.^M
/Daemons 
[root@host ~]# less /var/log/messages
...output omitted...
Feb 26 15:51:07 host NetworkManager[689]: <info>  [1551214267.8584] Loaded device plugin: NMTeamFactory (/usr/lib64/NetworkManager/1.14.0-14.el8/libnm-device-plugin-team.so)
Feb 26 15:51:07 host NetworkManager[689]: <info>  [1551214267.8599] device (lo): carrier: link connected
Feb 26 15:51:07 host NetworkManager[689]: <info>  [1551214267.8600] manager: (lo): new Generic device (/org/freedesktop/NetworkManager/Devices/1)
Feb 26 15:51:07 host NetworkManager[689]: <info>  [1551214267.8623] manager: (ens3): new Ethernet device (/org/freedesktop/NetworkManager/Devices/2)
Feb 26 15:51:07 host NetworkManager[689]: <info>  [1551214267.8653] device (ens3): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')
/device 

Ссылки

Man-страницы regex(7) и grep(1)