25.11.2023

Регулярные выражения linux. Регулярные выражения grep, egrep, sed в Linux


Для того, чтобы полноценно обрабатывать тексты в bash-скриптах с помощью sed и awk, просто необходимо разобраться с регулярными выражениями. Реализации этого полезнейшего инструмента можно найти буквально повсюду, и хотя устроены все регулярные выражения схожим образом, основаны на одних и тех же идеях, в разных средах работа с ними имеет определённые особенности. Тут мы поговорим о регулярных выражениях, которые подходят для использования в сценариях командной строки Linux.

Этот материал задуман как введение в регулярные выражения, рассчитанное на тех, кто может совершенно не знать о том, что это такое. Поэтому начнём с самого начала.

Что такое регулярные выражения

У многих, когда они впервые видят регулярные выражения, сразу же возникает мысль, что перед ними бессмысленное нагромождение символов. Но это, конечно, далеко не так. Взгляните, например, на это регулярное выражение

На наш взгляд даже абсолютный новичок сходу поймёт, как оно устроено и зачем нужно:) Если же вам не вполне понятно - просто читайте дальше и всё встанет на свои места.
Регулярное выражение - это шаблон, пользуясь которым программы вроде sed или awk фильтруют тексты. В шаблонах используются обычные ASCII-символы, представляющие сами себя, и так называемые метасимволы, которые играют особую роль, например, позволяя ссылаться на некие группы символов.

Типы регулярных выражений

Реализации регулярных выражений в различных средах, например, в языках программирования вроде Java, Perl и Python, в инструментах Linux вроде sed, awk и grep, имеют определённые особенности. Эти особенности зависят от так называемых движков обработки регулярных выражений, которые занимаются интерпретацией шаблонов.
В Linux имеется два движка регулярных выражений:

  • Движок, поддерживающий стандарт POSIX Basic Regular Expression (BRE).
  • Движок, поддерживающий стандарт POSIX Extended Regular Expression (ERE).

Большинство утилит Linux соответствуют, как минимум, стандарту POSIX BRE, но некоторые утилиты (в их числе - sed) понимают лишь некое подмножество стандарта BRE. Одна из причин такого ограничения - стремление сделать такие утилиты как можно более быстрыми в деле обработки текстов.

Стандарт POSIX ERE часто реализуют в языках программирования. Он позволяет пользоваться большим количеством средств при разработке регулярных выражений. Например, это могут быть специальные последовательности символов для часто используемых шаблонов, вроде поиска в тексте отдельных слов или наборов цифр. Awk поддерживает стандарт ERE.

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

Регулярные выражения POSIX BRE

Пожалуй, самый простой шаблон BRE представляет собой регулярное выражение для поиска точного вхождения последовательности символов в тексте. Вот как выглядит поиск строки в sed и awk:

$ echo "This is a test" | sed -n "/test/p" $ echo "This is a test" | awk "/test/{print $0}"

Поиск текста по шаблону в sed

Поиск текста по шаблону в awk

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

Работая с регулярными выражениями нужно учитывать то, что они чувствительны к регистру символов:

$ echo "This is a test" | awk "/Test/{print $0}" $ echo "This is a test" | awk "/test/{print $0}"

Регулярные выражения чувствительны к регистру

Первое регулярное выражение совпадений не нашло, так как слово «test», начинающееся с заглавной буквы, в тексте не встречается. Второе же, настроенное на поиск слова, написанного прописными буквами, обнаружило в потоке подходящую строку.

В регулярных выражениях можно использовать не только буквы, но и пробелы, и цифры:

$ echo "This is a test 2 again" | awk "/test 2/{print $0}"

Поиск фрагмента текста, содержащего пробелы и цифры

Пробелы воспринимаются движком регулярных выражений как обычные символы.

Специальные символы

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

.*^${}+?|()

Если один из них нужен в шаблоне, его нужно будет экранировать с помощью обратной косой черты (обратного слэша) - .

Например, если в тексте нужно найти знак доллара, его надо включить в шаблон, предварив символом экранирования. Скажем, имеется файл myfile с таким текстом:

There is 10$ on my pocket

Знак доллара можно обнаружить с помощью такого шаблона:

$ awk "/$/{print $0}" myfile

Использование в шаблоне специального символа

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

$ echo " is a special character" | awk "/\/{print $0}"

Экранирование обратного слэша

Хотя прямой слэш и не входит в приведённый выше список специальных символов, попытка воспользоваться им в регулярном выражении, написанном для sed или awk, приведёт к ошибке:

Неправильное использование прямого слэша в шаблоне

Если он нужен, его тоже надо экранировать:

$ echo "3 / 2" | awk "///{print $0}"

Экранирование прямого слэша

Якорные символы

Существуют два специальных символа для привязки шаблона к началу или к концу текстовой строки. Символ «крышка» - ^ позволяет описывать последовательности символов, которые находятся в начале текстовых строк. Если искомый шаблон окажется в другом месте строки, регулярное выражение на него не отреагирует. Выглядит использование этого символа так:

$ echo "welcome to likegeeks website" | awk "/^likegeeks/{print $0}" $ echo "likegeeks website" | awk "/^likegeeks/{print $0}"

Поиск шаблона в начале строки

Символ ^ предназначен для поиска шаблона в начале строки, при этом регистр символов так же учитывается. Посмотрим, как это отразится на обработке текстового файла:

$ awk "/^this/{print $0}" myfile


Поиск шаблона в начале строки в тексте из файла

При использовании sed, если поместить крышку где-нибудь внутри шаблона, она будет восприниматься как любой другой обычный символ:

$ echo "This ^ is a test" | sed -n "/s ^/p"

Крышка, находящаяся не в начале шаблона в sed

В awk, при использовании такого же шаблона, данный символ надо экранировать:

$ echo "This ^ is a test" | awk "/s ^/{print $0}"

Крышка, находящаяся не в начале шаблона в awk

С поиском фрагментов текста, находящихся в начале строки мы разобрались. Что, если надо найти нечто, расположенное в конце строки?

В этом нам поможет знак доллара - $ , являющийся якорным символом конца строки:

$ echo "This is a test" | awk "/test$/{print $0}"

Поиск текста, находящегося в конце строки

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

$ awk "/^this is a test$/{print $0}" myfile


Шаблон, в котором использованы специальные символы начала и конца строки

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

Вот как, пользуясь якорными символами, отфильтровать пустые строки:

$ awk "!/^$/{print $0}" myfile

В данном шаблоне использовал символ отрицания, восклицательный знак - ! . Благодаря использованию такого шаблона выполняется поиск строк, не содержащих ничего между началом и концом строки, а благодаря восклицательному знаку на печать выводятся лишь строки, которые не соответствуют этому шаблону.

Символ «точка»

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

$ awk "/.st/{print $0}" myfile


Использование точки в регулярных выражениях

Как видно по выведенным данным, шаблону соответствуют лишь первые две строки из файла, так как они содержат последовательность символов «st», предварённую ещё одним символом, в то время как третья строка подходящей последовательности не содержит, а в четвёртой она есть, но находится в самом начале строки.

Классы символов

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

Благодаря такому подходу можно организовать поиск любого символа из заданного набора. Для описания класса символов используются квадратные скобки - :

$ awk "/th/{print $0}" myfile


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

Тут мы ищем последовательность символов «th», перед которой есть символ «o» или символ «i».

Классы оказываются очень кстати, если выполняется поиск слов, которые могут начинаться как с прописной, так и со строчной буквы:

$ echo "this is a test" | awk "/his is a test/{print $0}" $ echo "This is a test" | awk "/his is a test/{print $0}"

Поиск слов, которые могут начинаться со строчной или прописной буквы

Классы символов не ограничены буквами. Тут можно использовать и другие символы. Нельзя заранее сказать, в какой ситуации понадобятся классы - всё зависит от решаемой задачи.

Отрицание классов символов

Классы символов можно использовать и для решения задачи, обратной описанной выше. А именно, вместо поиска символов, входящих в класс, можно организовать поиск всего, что в класс не входит. Для того, чтобы добиться такого поведения регулярного выражения, перед списком символов класса нужно поместить знак ^ . Выглядит это так:

$ awk "/[^oi]th/{print $0}" myfile


Поиск символов, не входящих в класс

В данном случае будут найдены последовательности символов «th», перед которыми нет ни «o», ни «i».

Диапазоны символов

В символьных классах можно описывать диапазоны символов, используя тире:

$ awk "/st/{print $0}" myfile


Описание диапазона символов в символьном классе

В данном примере регулярное выражение реагирует на последовательность символов «st», перед которой находится любой символ, расположенный, в алфавитном порядке, между символами «e» и «p».

Диапазоны можно создавать и из чисел:

$ echo "123" | awk "//" $ echo "12a" | awk "//"

Регулярное выражение для поиска трёх любых чисел

В класс символов могут входить несколько диапазонов:

$ awk "/st/{print $0}" myfile


Класс символов, состоящий из нескольких диапазонов

Данное регулярное выражение найдёт все последовательности «st», перед которыми есть символы из диапазонов a-f и m-z .

Специальные классы символов

В BRE имеются специальные классы символов, которые можно использовать при написании регулярных выражений:

  • [[:alpha:]] - соответствует любому алфавитному символу, записанному в верхнем или нижнем регистре.
  • [[:alnum:]] - соответствует любому алфавитно-цифровому символу, а именно - символам в диапазонах 0-9 , A-Z , a-z .
  • [[:blank:]] - соответствует пробелу и знаку табуляции.
  • [[:digit:]] - любой цифровой символ от 0 до 9 .
  • [[:upper:]] - алфавитные символы в верхнем регистре - A-Z .
  • [[:lower:]] - алфавитные символы в нижнем регистре - a-z .
  • [[:print:]] - соответствует любому печатаемому символу.
  • [[:punct:]] - соответствует знакам препинания.
  • [[:space:]] - пробельные символы, в частности - пробел, знак табуляции, символы NL , FF , VT , CR .

Использовать специальные классы в шаблонах можно так:

$ echo "abc" | awk "/[[:alpha:]]/{print $0}" $ echo "abc" | awk "/[[:digit:]]/{print $0}" $ echo "abc123" | awk "/[[:digit:]]/{print $0}"


Специальные классы символов в регулярных выражениях

Символ «звёздочка»

Если в шаблоне после символа поместить звёздочку, это будет означать, что регулярное выражение сработает, если символ появляется в строке любое количество раз - включая и ситуацию, когда символ в строке отсутствует.

$ echo "test" | awk "/tes*t/{print $0}" $ echo "tessst" | awk "/tes*t/{print $0}"


Использование символа * в регулярных выражениях

Этот шаблонный символ обычно используют для работы со словами, в которых постоянно встречаются опечатки, или для слов, допускающих разные варианты корректного написания:

$ echo "I like green color" | awk "/colou*r/{print $0}" $ echo "I like green colour " | awk "/colou*r/{print $0}"

Поиск слова, имеющего разные варианты написания

В этом примере одно и то же регулярное выражение реагирует и на слово «color», и на слово «colour». Это так благодаря тому, что символ «u», после которого стоит звёздочка, может либо отсутствовать, либо встречаться несколько раз подряд.

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

$ awk "/this.*test/{print $0}" myfile


Шаблон, реагирующий на любое количество любых символов

В данном случае неважно сколько и каких символов находится между словами «this» и «test».

Звёздочку можно использовать и с классами символов:

$ echo "st" | awk "/s*t/{print $0}" $ echo "sat" | awk "/s*t/{print $0}" $ echo "set" | awk "/s*t/{print $0}"


Использование звёздочки с классами символов

Во всех трёх примерах регулярное выражение срабатывает, так как звёздочка после класса символов означает, что если будет найдено любое количество символов «a» или «e», а также если их найти не удастся, строка будет соответствовать заданному шаблону.

Регулярные выражения POSIX ERE

Шаблоны стандарта POSIX ERE, которые поддерживают некоторые утилиты Linux, могут содержать дополнительные символы. Как уже было сказано, awk поддерживает этот стандарт, а вот sed - нет.

Тут мы рассмотрим наиболее часто используемые в ERE-шаблонах символы, которые пригодятся вам при создании собственных регулярных выражений.

▍Вопросительный знак

Вопросительный знак указывает на то, что предшествующий символ может встретиться в тексте один раз или не встретиться вовсе. Этот символ - один из метасимволов повторений. Вот несколько примеров:

$ echo "tet" | awk "/tes?t/{print $0}" $ echo "test" | awk "/tes?t/{print $0}" $ echo "tesst" | awk "/tes?t/{print $0}"


Вопросительный знак в регулярных выражениях

Как видно, в третьем случае буква «s» встречается дважды, поэтому на слово «tesst» регулярное выражение не реагирует.

Вопросительный знак можно использовать и с классами символов:

$ echo "tst" | awk "/t?st/{print $0}" $ echo "test" | awk "/t?st/{print $0}" $ echo "tast" | awk "/t?st/{print $0}" $ echo "taest" | awk "/t?st/{print $0}" $ echo "teest" | awk "/t?st/{print $0}"


Вопросительный знак и классы символов

Если символов из класса в строке нет, или один из них встречается один раз, регулярное выражение срабатывает, однако стоит в слове появиться двум символам и система уже не находит в тексте соответствия шаблону.

▍Символ «плюс»

Символ «плюс» в шаблоне указывает на то, что регулярное выражение обнаружит искомое в том случае, если предшествующий символ встретится в тексте один или более раз. При этом на отсутствие символа такая конструкция реагировать не будет:

$ echo "test" | awk "/te+st/{print $0}" $ echo "teest" | awk "/te+st/{print $0}" $ echo "tst" | awk "/te+st/{print $0}"


Символ «плюс» в регулярных выражениях

В данном примере, если символа «e» в слове нет, движок регулярных выражений не найдёт в тексте соответствий шаблону. Символ «плюс» работает и с классами символов - этим он похож на звёздочку и вопросительный знак:

$ echo "tst" | awk "/t+st/{print $0}" $ echo "test" | awk "/t+st/{print $0}" $ echo "teast" | awk "/t+st/{print $0}" $ echo "teeast" | awk "/t+st/{print $0}"


Знак «плюс» и классы символов

В данном случае если в строке имеется любой символ из класса, текст будет сочтён соответствующим шаблону.

▍Фигурные скобки

Фигурные скобки, которыми можно пользоваться в ERE-шаблонах, похожи на символы, рассмотренные выше, но они позволяют точнее задавать необходимое число вхождений предшествующего им символа. Указывать ограничение можно в двух форматах:

  • n - число, задающее точное число искомых вхождений
  • n, m - два числа, которые трактуются так: «как минимум n раз, но не больше чем m».

Вот примеры первого варианта:

$ echo "tst" | awk "/te{1}st/{print $0}" $ echo "test" | awk "/te{1}st/{print $0}"

Фигурные скобки в шаблонах, поиск точного числа вхождений

В старых версиях awk нужно было использовать ключ командной строки --re-interval для того, чтобы программа распознавала интервалы в регулярных выражениях, но в новых версиях этого делать не нужно.

$ echo "tst" | awk "/te{1,2}st/{print $0}" $ echo "test" | awk "/te{1,2}st/{print $0}" $ echo "teest" | awk "/te{1,2}st/{print $0}" $ echo "teeest" | awk "/te{1,2}st/{print $0}"


Интервал, заданный в фигурных скобках

В данном примере символ «e» должен встретиться в строке 1 или 2 раза, тогда регулярное выражение отреагирует на текст.

Фигурные скобки можно применять и с классами символов. Тут действуют уже знакомые вам принципы:

$ echo "tst" | awk "/t{1,2}st/{print $0}" $ echo "test" | awk "/t{1,2}st/{print $0}" $ echo "teest" | awk "/t{1,2}st/{print $0}" $ echo "teeast" | awk "/t{1,2}st/{print $0}"


Фигурные скобки и классы символов

Шаблон отреагирует на текст в том случае, если в нём один или два раза встретится символ «a» или символ «e».

▍Символ логического «или»

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

$ echo "This is a test" | awk "/test|exam/{print $0}" $ echo "This is an exam" | awk "/test|exam/{print $0}" $ echo "This is something else" | awk "/test|exam/{print $0}"


Логическое «или» в регулярных выражениях

В данном примере регулярное выражение настроено на поиск в тексте слов «test» или «exam». Обратите внимание на то, что между фрагментами шаблона и разделяющим их символом | не должно быть пробелов.

Фрагменты регулярных выражений можно группировать, пользуясь круглыми скобками. Если сгруппировать некую последовательность символов, она будет восприниматься системой как обычный символ. То есть, например, к ней можно будет применить метасимволы повторений. Вот как это выглядит:

$ echo "Like" | awk "/Like(Geeks)?/{print $0}" $ echo "LikeGeeks" | awk "/Like(Geeks)?/{print $0}"


Группировка фрагментов регулярных выражений

В данных примерах слово «Geeks» заключено в круглые скобки, после этой конструкции идёт знак вопроса. Напомним, что вопросительный знак означает «0 или 1 повторение», в результате регулярное выражение отреагирует и на строку «Like», и на строку «LikeGeeks».

Практические примеры

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

▍Подсчёт количества файлов

Напишем bash-скрипт, который подсчитывает файлы, находящиеся в директориях, которые записаны в переменную окружения PATH . Для того, чтобы это сделать, понадобится, для начала, сформировать список путей к директориям. Сделаем это с помощью sed, заменив двоеточия на пробелы:

$ echo $PATH | sed "s/:/ /g"

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

Mypath=$(echo $PATH | sed "s/:/ /g") for directory in $mypath do done

Теперь напишем полный текст скрипта, воспользовавшись командой ls для получения сведений о количестве файлов в каждой из директорий:

#!/bin/bash mypath=$(echo $PATH | sed "s/:/ /g") count=0 for directory in $mypath do check=$(ls $directory) for item in $check do count=$[ $count + 1 ] done echo "$directory - $count" count=0 done

При запуске скрипта может оказаться, что некоторых директорий из PATH не существует, однако, это не помешает ему посчитать файлы в существующих директориях.


Подсчёт файлов

Главная ценность этого примера заключается в том, что пользуясь тем же подходом, можно решать и куда более сложные задачи. Какие именно - зависит от ваших потребностей.

▍Проверка адресов электронной почты

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

[email protected]

Имя пользователя, username , может состоять из алфавитно-цифровых и некоторых других символов. А именно, это точка, тире, символ подчёркивания, знак «плюс». За именем пользователя следует знак @.

Вооружившись этими знаниями, начнём сборку регулярного выражения с его левой части, которая служит для проверки имени пользователя. Вот что у нас получилось:

^(+)@

Теперь - очередь имени хоста - hostname . Тут применимы те же правила, что и для имени пользователя, поэтому шаблон для него будет выглядеть так:

(+)

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

.({2,5})$

Прочесть его можно так: «Сначала должна быть точка, потом - от 2 до 5 алфавитных символов, а после этого строка заканчивается».

Подготовив шаблоны для отдельных частей регулярного выражения, соберём их вместе:

^(+)@(+).({2,5})$

Теперь осталось лишь протестировать то, что получилось:

$ echo "[email protected]" | awk "/^(+)@(+).({2,5})$/{print $0}" $ echo "[email protected]" | awk "/^(+)@(+).({2,5})$/{print $0}"


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

То, что переданный awk текст выводится на экран, означает, что система распознала в нём адрес электронной почты.

Итоги

Если регулярное выражение для проверки адресов электронной почты, которое встретилось вам в самом начале статьи, казалось тогда совершенно непонятным, надеемся, сейчас оно уже не выглядит бессмысленным набором символов. Если это действительно так - значит данный материал выполнил своё предназначение. На самом деле, регулярные выражения - это тема, которой можно заниматься всю жизнь, но даже то немногое, что мы разобрали, уже способно помочь вам в написании скриптов, которые довольно продвинуто обрабатывают тексты.

В этой серии материалов мы обычно показывали очень простые примеры bash-скриптов, которые состояли буквально из нескольких строк. В следующий раз рассмотрим кое-что более масштабное.

Уважаемые читатели! А вы пользуетесь регулярными выражениями при обработке текстов в сценариях командной строки?

Утилита grep — это очень мощное средство для поиска и фильтрации текстовой информации. В этой статье показаны несколько примеров ее использования, которые позволят по достоинству оценить ее возможности.
Основная сфера применения grep – поиск слов или фраз в файлах и потоках вывода. Вы можете осуществить поиск, набрав в командной строке запрос и область поиска (файл).
Например, чтобы найти строку “needle” в файле hystack.txt используйте следующую команду:

$ grep needle haystack.txt

В результате grep отобразит все вхождения needle, которые он встретит в содержимом файла haystack.txt. Важно заметить, что в этом случае grep ищет именно набор символов, а не слово. Например, будут отображены строки, включающие слово “needless” и другие слова, в которых встречается последовательность “needle”.


Чтобы указать grep, что вы ищете именно слово, используйте ключ -w. Этот ключ ограничит область поиска только указанным словом. Под словом подразумевается запрос, ограниченный с обоих сторон любыми пробельными символами, знаками пунктуации или переносами строки.

$ grep -w needle haystack.txt

Не обязательно ограничивать область поиска только одним файлом, grep может выполнять поиск и по группе файлов, причем в результатах поиска будет указан файл, в котором обнаружено совпадение. Ключ -n добавит еще и номер строки, в которой обнаружено совпадение, а ключ -r позволит выполнить рекурсивный поиск. Это очень удобно при поиске среди файлов с исходными текстами программ.

$ grep -rnw function_name /home/www/dev/myprogram/

Имя файла будет указано перед каждым совпадением. Если вам необходимо скрыть имена файлов, воспользуйтесь ключом -h, напротив, если необходимы только имена файлов, то укажите ключ -l
В следующем примере мы выполним поиск URL-адресов в лог-файле IRC и покажем последние 10 совпадений.

$ grep -wo http://.* channel.log | tail

Параметр -o указывает grep, что следует выводить лишь совпадение с шаблоном, а не всю строку. Вывод grep при помощи pipe перенаправляем команде tail, которая по умолчанию выводит 10 последних строк.
Теперь мы подсчитаем количество сообщений, посланных в irc-канал определенными пользователями. Например, все сообщения, которые я послал из дома и с работы. Они отличаются по никнейму, дома я использую ник user_at_home, а на работе user_at_work.

$ grep -c "^user_at_(home|work)" channel.log

С параметром -c grep выводит лишь количество найденных совпадений, а не сами совпадения. Строка поиска заключена в кавычки потому, что в ней содержатся специальные символы, которые могут распознаны оболочкой как управляющие. Обратите внимание, что кавычки не входят в шаблон поиска. Обратный слэш "" служит для экранирования служебных символов.
Выполним поиск по сообщениям людей, которые любят “кричать” в канале. Под “криком” мы понимаем сообщения, написанные в blondy-style, одними ЗАГЛАВНЫМИ буквами. Чтобы исключить из поиска случайные попадания аббревиатур, будем искать слова из пяти и более символов:

$ grep -w "+{5,}" channel.log

За более детальным описанием можно обратиться к странице руководства man grep.
Еще несколько примеров:

# grep root /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin

Отображает строки из файла /etc/passwd, в которых есть строка root.

# grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/bash 12:operator:x:11:0:operator:/root:/sbin/nologin

Отображаются, кроме того, номера строк, в которых есть искомая строка.

# grep -v bash /etc/passwd | grep -v nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt news:x:9:13:news:/var/spool/news: mailnull:x:47:47::/var/spool/mqueue:/dev/null xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false rpc:x:32:32:Portmapper RPC user:/:/bin/false nscd:x:28:28:NSCD Daemon:/:/bin/false named:x:25:25:Named:/var/named:/bin/false squid:x:23:23::/var/spool/squid:/dev/null ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false apache:x:48:48:Apache:/var/www:/bin/false

Проверяется, кто из пользователей не использует bash, исключая те аккаунты пользователей, у которых в качестве оболочки указан nologin.

# grep -c false /etc/passwd 7

Подсчитывает количество учетных записей, в которых в качестве командной оболочки указано /bin/false.

# grep -i games ~/.bash* | grep -v history

В этой команде отображаются строки из всех файлов домашнего каталога текущего пользователя, имена которых начинаются с ~/.bash, за исключением тех файлов, в именах которых есть строка history, с тем, чтобы исключить соответствия, имеющиеся в файле ~/.bash_history, в котором может быть указана одна и та же строка в верхнем или нижнем регистрах. Обратите внимание, что осуществляется поиск слова «games», вместо него можно подставить любое другое.
Команда grep и регулярные выражения

В отличие от предыдущего примера, теперь отобразим только те строки, которые начинаются со строки «root»:

# grep ^root /etc/passwd root:x:0:0:root:/root:/bin/bash

Если мы хотим увидеть, в каких учетных записях командная оболочка вообще не использовалась, мы ищем строки, заканчивающиеся сиволом «:»:

# grep:$ /etc/passwd news:x:9:13:news:/var/spool/news:

Чтобы проверить, экспортируется ли в файле ~/.bashrc переменная PATH, сначала выберите строки с «export», а затем найдите строки, начинающиеся со строки «PATH»; в таком случае не будут отображаться MANPATH и другие возможные пути:

# grep export ~/.bashrc | grep "PATH" export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"

Символьные классы

Выражением в квадратных скобках является список символов, заключенных внутри символов [" и "]"". Оно соответствует любому одиночному символу, указанному в этом списке; если первый символ списка есть «^», то оно соответствует любому символу, который ОТСУТСВУЕТ в списке. Например, регулярное выражение "" соответствует любой одиночной цифре.

Внутри выражения в квадратных скобках можно указывать диапазон, состоящий из двух символов, разделенных дефисом. Тогда выражение соответствует любому одиночному, который согласно правилам сортировки попадает внутрь этих двух символов, включая и эти два символа; при этом учитывается последовательность упорядочивания и набор символов, указанные в локали. Например, когда по умолчанию указана локаль C, выражение "" эквивалентно выражению "". Есть много локалей, в которых сортировка выполняется в словарном порядке, и в этих локалях "", как правило, не эквивалентно "", в них, например, оно может быть эквивалентно выражению "". Чтобы использовать традиционную интерпретацию выражения, указываемого в квадратных скобках, вы можете воспользоваться локалью C, установив для этого в переменной окружения LC_ALL значение «C».

Наконец, есть определенным образом поименованные символьные классы, которые указываются внутри выражений в квадратных скобках. Дополнительную информацию об этих предопределенных выражениях смотрите на страницах man или в документации команды grep.

# grep /etc/group sys:x:3:root,bin,adm tty:x:5: mail:x:12:mail,postfix ftp:x:50: nobody:x:99: floppy:x:19: xfs:x:43: nfsnobody:x:65534: postfix:x:89:

В примере отображаются все строки, содержащие либо символ «y», либо символ «f».
Универсальные символы (метасимволы)

Используйте «.» для поиска соответствия любому одиночному символу. Если вы хотите получить список всех английских слов, взятых из словаря, содержащих пять символов, начинающихся с «c» и заканчивающихся «h» (удобно для решения кроссвордов):

# grep "" /usr/share/dict/words catch clash cloth coach couch cough crash crush

Если вы хотите отобразить строки, в которых есть символ точки в виде литерала, то укажите в команде grep параметр -F. Символы "< " и «>» означают наличие пустой строки до и соответственно после указанных букв. Это значит, что слова в файл words должны быть записаны соответствующим образом. Если вы хотите найти все слова в тексте по указанному шаблоны без учета пустых строк опустите символы "< " и «>», для более точного поиска только слов используйте ключ -w.

Чтобы подобным образом найти слова, в которых между «c» и «h» может находиться любое число символов, используйте звездочку (*). В приведенном ниже примере из системного словаря выбираются все слова, начинающиеся с «c» и заканчивающиеся символом «h»:

# grep "" /usr/share/dict/words caliph cash catch cheesecloth cheetah --output omitted--

Если вы хотите найти в файле или в выходном потоке литеральный символ «звездочка», используйте для этого одинарные кавычки. Пользователь в приведенном ниже примере сначала пытается в файле /etc/profile найти «звездочку» без использования кавычек, в результате чего ничего не находится. Когда используются кавычки, в выходной поток выдается результат:

# grep * /etc/profile # grep "*" /etc/profile for i in /etc/profile.d/*.sh ; do

Одна из наиболее полезных и многофункциональных команд в терминале Linux – команда «grep». Название представляет собой акроним английской фразы «search Globally for lines matching the Regular Expression, and Print them» (искать везде соответствующие регулярному выражению строки и выводить их). Команда «grep» просматривает входной поток последовательно, строка за строкой, в поисках совпадений и выводит (отфильтровывает) только те строки, которые содержат текст, совпадающий с заданным шаблоном – регулярным выражением .

Регулярные выражения - специальный формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов. Сейчас уже практически все современные языки программирования имеют встроенную поддержку регулярных выражений для обработки текстов, однако исторически популяризации данного подхода во многом способствовал именно мир UNIX и в частности идеи, заложенные в команды «grep», «sed» и др. Философия «все есть файл» полностью пронизывает UNIX и владение инструментами для работы с текстовыми файлами является одним из обязательных навыков каждого пользователя Linux.

ОБРАЗЕЦ

GIST | Простейший поиск всех строк, в которых есть текст «Adams». При оформлении этого и последующих примеров будем придерживаться следующего порядка: сверху параметры командной строки, внизу стандартные потоки слева ввода stdin и справа вывода stdout .

Команда «grep» имеет внушительное количество опций, которые можно указать при запуске. С помощью этих опций можно делать много полезных вещей и при этом в принципе даже не обязательно хорошо разбираться в синтаксисе регулярных выражений.

ОПЦИИ

Начнём с того, что «grep» умеет не только фильтровать стандартный ввод stdin , но и осуществлять поиск по файлам. По умолчанию «grep» будет искать только в файлах, находящихся в текущем каталоге, однако при помощи очень полезной опции --recursive можно сказать команде «grep» искать рекурсивно начиная с заданной директории.

GIST | По умолчанию команда «grep» чувствительна к регистру. Следующий пример показывает как можно искать и при этом не учитывать регистр, например «Adams» и «adams» одно и то же:

Ignore-case "adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801

GIST | Поиск наоборот (иногда говорят инвертный поиск), то есть будут выведены все строки, кроме имеющих вхождение указанного шаблона:

Invert-match "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington, 1789-1797 Thomas Jefferson, 1801-1809

GIST | Опции конечно же можно и нужно комбинировать друг с другом. Например поиск наоборот с выводом порядковых номеров строк с вхождениями:

Line-number --invert-match "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 1:George Washington, 1789-1797 3:Thomas Jefferson, 1801-1809

GIST | Раскраска. Иногда удобно, когда искомое нами слово подсвечивается цветом. Все это уже есть в «grep», остается только включить:

Line-number --color=always "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 2:John Adams, 1797-1801

GIST | Мы хотим выбрать все ошибки из лог файла, но знаем что в следующей сточке после ошибки может содержаться полезная информация, тогда удобно вывести несколько строк из контекста. По умолчанию «grep» выводит лишь строку, в которой было найдено совпадение, но есть несколько опций, позволяющих заставить «grep» выводить больше. Для вывода нескольких строк (в нашем случае двух) после вхождения:

Color=always -A2 "Adams"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817

GIST | Аналогично для дополнительного вывода нескольких строк перед вхождением:

Color=always -B2 "James"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825

GIST | Однако чаще всего требуется выводить симметричный контекст, для этого есть ещё более сокращённая запись. Выведем по две строки как сверху так и снизу от вхождения:

Color=always -C2 "James"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Quincy Adams, 1825-1829 Andrew Jackson, 1829-1837 Martin Van Buren, 1837-1841 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 James Madison, 1809-1817 James Monroe, 1817-1825 John Quincy Adams, 1825-1829 Andrew Jackson, 1829-1837

GIST | Когда Вы ищете qwe , то по умолчанию «grep» будет выводить также, qwe123 , 345qwerty и тому подобные комбинации. Найдём только те строки, которые выключают именно всё слово целиком:

Word-regexp --color=always "John"

John Fitzgerald Kennedy, 1961-1963 Lyndon Baines Johnson, 1963-1969 John Fitzgerald Kennedy, 1961-1963

GIST | Ну и напоследок если Вы просто хотите знать количество строк с совпадениями одним единственным числом, но при этом не выводить больше ничего:

Count --color=always "John"

John Fitzgerald Kennedy, 1961-1963 Lyndon Baines Johnson, 1963-1969 Richard Milhous Nixon, 1969-1974 2

Стоит отметить, что у большинства опций есть двойник, например --ignore-case можно привести к более короткому виду -i и т.д.

БАЗОВЫЕ РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ

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

Знак каретки ^ и доллара $ имеют в регулярном выражении особый смысл. Их называют «якорями» (anchor). Якоря – это специальные символы, которые указывают местонахождение в строке необходимого совпадения. Когда поиск доходит до якоря, он проверяет, есть ли соответствие, и если есть – продолжает идти по шаблону, не прибавляя ничего к результату .

GIST | Якорь каретка используют чтобы указать, что регулярное выражение необходимо проверить именно с начала строки:

Color=always "^J"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801

GIST | Аналогично якорь доллар стоит использовать в конце шаблона, чтобы указать, что совпадение действительно только если искомая строка символов находится в конце текстовой строки и никак иначе:

Color=always "9$"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 Thomas Jefferson, 1801-1809

GIST | Любой символ. Символ точка используется в регулярных выражениях для того, чтобы обозначить, что в указанном месте может находиться абсолютно любой символ:

Color=always "0.$"

GIST | Экранирование. Если нужно найти именно символ точка, тогда экранирование в помощь. Знак экранирования (как правило это обратный слеш), предшествующий символу вроде точки, превращает метасимвол в литерал:

Color=always "\."

George Washington. 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington. 1789-1797

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

Color=always "0"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801 Thomas Jefferson, 1801-1809

GIST | Диапазон. Это два символа, разделенные дефисом, например, 0-9 (десятичные цифры) или 0-9a-fA-F (шестнадцатеричные цифры):

Color=always ""

George Washington, ??? John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801 Thomas Jefferson, 1801-1809

GIST | Отрицание. Если первым символом выражения в квадратных скобках является каретка, то остальные символы принимаются как набор символов, которые не должны присутствовать в заданной позиции регулярного выражения:

Color=always "[^7]$"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 John Adams, 1797-1801 Thomas Jefferson, 1801-1809

GIST | Классы символов POSIX. Существует некий набор уже заранее заготовленных классов символов, которые Вы можете использовать в регулярных выражениях. Их там с десяток, достаточно быстро просмотреть мануал чтобы понять назначение каждого. Например отфильтруем только шестнадцатеричные цифры:

Color=always "^[[:xdigit:]]*$"

4.2 42 42abc 42 42abc

GIST | Повторение (0 или больше раз). Одним из наиболее часто используемых метасимволов является символ звёздочка, что означает «повторить предыдущий символ или выражение ноль или больше раз»:

Color=always "^*$"

George Washington, ??? John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington, ???

Различают базовые регулярные выражения BRE (basic regular expressions) и расширенные ERE (extended regular expressions). В BRE распознаются следующие метасимволы ^ $ . * и все другие символы расцениваются как литералы. В ERE добавлены ещё такие метасимволы () { } ? + | и связанные с ними функции. Ну а чтобы всех окончательно запутать в «grep» придумали такую штуку – символы () { } в BRE обрабатываются как метасимволы, если они экранированы обратным слешем, в то время как в ERE постановка перед любыми метасимволами обратного слеша приводит к тому, что они трактуются как литералы.

РАСШИРЕННЫЕ РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ

GIST | Дизъюнкция. Подобно тому, как квадратные скобки задают различные возможные варианты совпадения одного символа, дизъюнкция позволяет указать альтернативные совпадения для строк символов или выражений. Для обозначения дизъюнкции используется символ вертикальной черты:

Extended-regexp --color=always "George|John"

George Washington, 1789-1797 John Adams, 1797-1801 Thomas Jefferson, 1801-1809 George Washington, 1789-1797 John Adams, 1797-1801

GIST | Совпадение ноль или один раз. В расширенных регулярных выражениях существуют несколько дополнительных метасимволов, указывающих частоту повторения символа или выражения (подобно тому, как метасимвол звездочка указывает на совпадения 0 или более раз). Один из таких метасимволов это вопросительный знак, который делает предыдущий символ или выражение, по сути, необязательными:

Extended-regexp --color=always "^(Andrew)?John"

John Adams, 1797-1801 Andrew Johnson, 1865-1869 Lyndon Baines Johnson, 1963-1969 John Adams, 1797-1801 Andrew Johnson, 1865-1869

GIST | Совпадение один или более раз. Для этого предусмотрен метасимвол в виде знака плюс. Он работает почти как символ звездочка, за исключением того, что выражение должно совпасть хотя бы один раз:

Extended-regexp --color=always "^[[:alpha:] ]+$"

John Adams Andrew Johnson, 1865-1869 Lyndon Baines Johnson, 1963-1969 John Adams

GIST | Совпадение указанное количество раз. Для этого можно использовать фигурные скобки. Эти метасимволы используются для указания точного количества, диапазона, а также верхнего и нижнего предела количества совпадений выражения:

Extended-regexp --color=always "{1,3}\.{1,3}\.{1,3}\.{1,3}"

42 127.0.0.1 127.0.0.1

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

Доброго времени, гости!

В сегодняшней статье хочу коснуться такой огромной темы как Регулярные выражения . Думаю всем известно, что тема регексов (так регулярные выражения называются на сленге) - необъятна в объеме одного поста. Посему постараюсь кратко, но как можно понятней собрать в кучу свои мысли и донести их до Вас в .

Начну с того, что существует несколько разновидностей регулярных выражений:

1. Традиционные регулярные выражения (они же основные, базовые и basic regular expressions (BRE))

  • синтаксис данных выражений определен, как устаревший, но тем не менее до сих пор широко распространен и используется многими утилитами UNIX
  • Основные регулярные выражения включают в себя следующие метасимволы (об их значениях ниже):
    • \{ \} - первоначальный вариант для { } (в расширенных)
    • \(\) - первоначальный вариант для () (в расширенных)
    • \n , где n - номер от 1 до 9
  • Особенности использования данных метасимволов:
    • Звёздочка должна следовать после выражения, соответствующего единичному символу. Пример: * .
    • Выражение \(блок \)* следует считать неправильным. В некоторых случаях оно соответствует нулю или более повторений строки блок . В других оно соответствует строке блок * .
    • Внутри символьного класса специальные значения символов, в основном, игнорируются. Особые случаи:
    • Чтобы добавить символ ^ в набор, его следует поместить туда не первым.
    • Чтобы добавить символ - в набор, его следует поместить туда первым или последним. Например:
      • шаблон DNS-имени, куда могут входить буквы, цифры, минус и точка-разделитель: [-0-9a-zA-Z.] ;
      • любой символ, кроме минуса и цифры: [^-0-9] .
    • Чтобы добавить символ [ или ] в набор, его следует поместить туда первым. Например:
      • соответствует ] , [ , a или b .

2. Расширенные регулярные выражения (они же extended regular expressions (ERE))

  • Синтаксис данных выражений аналогичен синтаксису основных выражений, за исключением:
    • Отменено использование обратной косой черты для метасимволов { } и () .
    • Обратная косая черта перед метасимволом отменяет его специальное значение.
    • Отвергнута теоретически нерегулярная конструкция \n .
    • Добавлены метасимволы + , ? , | .

3. Регулярные выражения, совместимые с Perl (они же Perl-compatible regular expressions (PCRE))

  • имеют более богатый и в то же время предсказуемый синтаксис, чем даже POSIX ERE, поэтому часто используется приложениями.

Регулярные выражения состоят из шаблонов, вернее сказать задают шаблон поиска. Шаблон состоит из правил поиска, которые составляются из символов и метасимволов .

Правила поиска определяются следующими операциями :

Перечисление |

Вертикальная черта (|) разделяет допустимые варианты, можно сказать - логическое ИЛИ. Например, «gray|grey» соответствует gray или grey .

Группировка или объединение ()

Круглые скобки используются для определения области действия и приоритета операторов. Например, «gray|grey» и «gr(a|e)y» являются разными образцами, но они оба описывают множество, содержащее gray и grey .

Квантификация {} ? * +

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

общее выражение, повторений может быть от m до n включительно .

общее выражение, m и более повторений .

общее выражение, не более n повторений .

ровно n повторений .

Знак вопроса означает 0 или 1 раз, то же самое, что и {0,1} . Например, «colou?r» соответствует и color , и colour .

Звёздочка означает 0, 1 или любое число раз ({0,} ). Например, «go*gle» соответствует ggle , gogle , google и др.

Плюс означает хотя бы 1 раз ({1,} ). Например, «go+gle» соответствует gogle , google и т. д. (но не ggle ).

Конкретный синтаксис данных регулярных выражений зависит от реализации. (то есть в базовых регулярных выражениях символы { и } - экранируются обратным слешем)

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

. соответствует одному любому символу
[что-то] Соответствует любому единичному символу из числа заключённых в скобки. При этом:Символ «-» интерпретируется буквально только в том случае, если он расположен непосредственно после открывающей или перед закрывающей скобкой: или [-abc]. В противном случае, он обозначает интервал символов.Например, соответствует «a», «b» или «c». соответствует буквам нижнего регистра латинского алфавита. Эти обозначения могут и сочетаться: соответствует a, b, c, q, r, s, t, u, v, w, x, y, z.Чтобы установить соответствие символам «[» или «]», достаточно, чтобы закрывающая скобка была первым символом после открывающей: соответствует «]», «[», «a» или «b».Если значение в квадратных скобах предварено символом ^, то значение выражения соответствует единичному символу из числа тех, которых нет в скобках . Например, [^abc] соответствует любому символу, кроме «a», «b» или «c». [^a-z] соответствует любому символу, кроме символов нижнего регистра в латинском алфавите.
^ Соответствует началу текста (или началу любой строки, если режим построчный).
$ Соответствует концу текста (или концу любой строки, если режим построчный).
\(\) или () Объявляет «отмеченное подвыражение» (сгруппированное выражение), которое может быть использовано позже (см. следующий элемент: \n ). «Отмеченное подвыражение» также является «блоком». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша, в расширенном и Perl символ \ - не нужен.
\n Где n - это цифра от 1 до 9; соответствует n -му отмеченному подвыражению (например (abcd)\0, то есть символы abcd отмечены нулем). Эта конструкция теоретически нерегулярна , она не была принята в расширенном синтаксисе регулярных выражений.
*
  • Звёздочка после выражения, соответствующего единичному символу, соответствует нулю или более копий этого (предшествующего) выражения. Например, «*» соответствует пустой строке, «x», «y», «zx», «zyx», и т. д.
  • \n *, где n - это цифра от 1 до 9, соответствует нулю или более вхождений для соответствия n -го отмеченного подвыражения. Например, «\(a.\)c\1*» соответствует «abcab» и «abcaba», но не «abcac».

Выражение, заключённое в «\(» и «\)» и сопровождаемое «*», следует считать неправильным. В некоторых случаях, оно соответствует нулю или более вхождений строки, которая была заключена в скобки. В других, оно соответствует выражению, заключённому в скобки, учитывая символ «*».

\{x ,y \} Соответствует последнему (предстоящему ) блоку, встречающемуся не менее x и не более y раз. Например, «a\{3,5\}» соответствует «aaa», «aaaa» или «aaaaa». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша.
.* Обозначение любого количества любых символов между двумя частями регулярного выражения.

Метасимволы нам помогают использовать различные соответствия. Но как же представить метасимвол обычным символом, то есть символ [ (квадратная скобка) значением квадратной скобки? Просто:

  • необходимо предварить (экранировать ) метасимвол (. * + \ ? { }) обратным слешем. Например \. или \[

Для упрощения задания некоторых наборов символов, их объединили в т.н.классы и категории символов . POSIX стандартизовал объявление некоторых классов и категорий символов, как показано в следующей таблице:

POSIX класс аналогично обозначение
[:upper:] символы верхнего регистра
[:lower:] символы нижнего регистра
[:alpha:] символы верхнего и нижнего регистра
[:alnum:] цифры, символы верхнего и нижнего регистра
[:digit:] цифры
[:xdigit:] шестнадцатеричные цифры
[:punct:] [.,!?:…] знаки пунктуации
[:blank:] [ \t] пробел и TAB
[:space:] [ \t\n\r\f\v] символы пропуска
[:cntrl:] символы управления
[:graph:] [^ \t\n\r\f\v] символы печати
[:print:] [^\t\n\r\f\v] символы печати и символы пропуска

В regex есть такое понятие как:

Жадность regex

Постараюсь описать как можно понятней. Допустим, мы хотим найти все HTML теги в каком-то тексте. Локализовав задачу, мы хотим найти значения заключенные между < и >, вместе с этими самыми скобками. Но мы знаем, что теги имеют разную длину и самих тегов, как минимум штук 50. Перечислять их все, заключив в метасимволы - задача слишком трудоемкая. Но мы знаем, что у нас есть выражение.* (точка звездочка), характеризующее любое число любых символов в строке. С помощью данного выражения мы попытаемся найти в тексте (

Итак, Как создать RAID уровня 10/50 на контроллере LSI MegaRAID (актуально и для: Intel SRCU42x, Intel SRCS16):

) все значения между < и >. В результате, этому выражению будет соответствовать ВСЯ строка. почему, потому что регекс - ЖАДЕН и старается захватить ЛЮБОЕ ВСЕ количество символов между < и >, соответственно вся строка, начиная < p>Итак,... и заканчивая ...> будет принадлежать данному правилу!

Надеюсь, на примере понятно что такое жадность. Чтобы избавиться от данной жадности, можно пойти по следующему пути:

  • учесть символы, не соответствующие желаемому образцу (например: <[^>]*> для вышеописанного случая)
  • избавить от жадности, добавив определении квантификатора, как нежадного:
    • *? - «не жадный» («ленивый») эквивалент *
    • +? - «не жадный» («ленивый») эквивалент +
    • {n,}? - «не жадный» («ленивый») эквивалент {n,}
    • .*? - «не жадный» («ленивый») эквивалент.*

Все вышенаписанное хочу дополнить синтаксисом расширенных регулярных выражений:

Регулярные выражения в POSIX аналогичны традиционному Unix-синтаксису, но с добавлением некоторых метасимволов:

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

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

Вертикальная черта разделяет альтернативные варианты регулярных выражений. Один символ задаёт две альтернативы, но их может быть и больше, достаточно использовать больше вертикальных чёрточек. Необходимо помнить, что этот оператор использует максимально возможную часть выражения. По этой причине, оператор альтернативы чаще всего используется внутри скобок.

Также было отменено использование обратной косой черты: \{…\} становится {…} и \(…\) становится (…).

В завершение поста, приведу некоторые примеры использования regex:

$ cat text1 1 apple 2 pear 3 banana $ grep p text1 1 apple 2 pear $ grep "pp*" text1 1 apple 2 pear $ cat text1 | grep "l\|n" 1 apple 3 banana $ echo -e "find an\n* here" | grep "\*" * here $ grep "pl\?.*r" text1 # p, в строках где есть r 2 pear $ grep "a.." text1 # строки с a, за которой следует как минимум 2 символа 1 apple 3 banana $ grep "" text1 # поиск строк, где есть 3 или p 1 apple 2 pear 3 banana $ echo -e "find an\n* here\nsomewhere." | grep "[.*]" * here somewhere..name]$ echo -e "123\n456\n789\n0" | grep "" 123 456 789 $ sed -e "/\(a.*a\)\|\(p.*p\)/s/a/A/g" text1 # замена а на А во всех строках, где после а идет а или после р идет р 1 Apple 2 pear 3 bAnAnA *\./ LAST WORD./g" First. A LAST WORD. This is a LAST WORD.

С Уважением, Mc.Sim!

grep расшифровывается как ‘global regular expression printer‘. grep отрезает нужные вам строки из текстовых файлов которые содержат указанный пользователем текст.

grep может быть использован двумя путями - сам по себе или в комбинации с потоками.

grep очень обширен в функциональности, за счет большого количества поддерживаемых им опций, таких как: поиск с использованием строкового шаблона или RegExp регулярных выражений шаблон или perl based регулярных выражений и т.д.

Из-за его различных функциональных возможностей инструмент grep имеет множество вариантов, включая egrep (Extended GREP) , fgrep (Fixed GREP) , pgrep (Process GREP) , rgrep (рекурсивный GREP) и т.д. Но эти варианты имеют незначительные отличия от оригинального grep.

Параметры grep

$ grep -V grep (GNU grep) 2.10 Copyright (C) 2011 Free Software Foundation, Inc. Лицензия GPLv3+

Существуют модификации утилиты grep: egrep (с обработкой расширенных регулярных выражений), fgrep (трактующая символы $*^|()\ как литералы, т.е. буквально), rgrep (с включённым рекурсивным поиском).

    egrep то же самое что grep -E

    fgrep то же самое что grep -F

    rgrep то же самое что grep -r

    grep [-b] [-c] [-i] [-l] [-n] [-s] [-v] ограниченное_регулярное_выражение_BRE [файл …]

Команда grep сопоставляет строки исходных файлов с шаблоном, заданным ограниченным_регулярным_выражением. Если файлы не указаны, используется стандартный ввод. Обычно каждая успешно сопоставленная строка копируется на стандартный вывод; если исходных файлов несколько, перед найденной строкой выдается имя файла. В grep используется компактный недетерминированный алгоритм. В качестве шаблонов воспринимаются ограниченные регулярные выражения (выражения, имеющие своими значениями цепочки символов, и использующие ограниченный набор алфавитно-цифровых и специальных символов). Они имеют тот же смысл, что и регулярные выражения в ed.

Для экранирования символов $, *, , ^, |, (), и \ от интерпретации shell"ом проще всего заключать ограниченное_регулярное_выражение в одинарные кавычки.

Опции:

B Предваряет каждую строку номером блока, в котором она была найдена. Это может пригодиться при поиске блоков по контексту (блоки нумеруются с 0). -c Выдает только количество строк, содержащих образец. -h Предотвращает выдачу имени файла, содержащего сопоставившуюся строку, перед собственно строкой. Используется при поиске по нескольким файлам. -i Игнорирует регистр символов при сравнениях. -l Выдает только имена файлов, содержащих сопоставившиеся строки, по одному в строке. Если образец найден в нескольких строках файла, имя файла не повторяется. -n Выдает перед каждой строкой ее номер в файле (строки нумеруются с 1). -s Подавляет выдачу сообщений о не существующих или недоступных для чтения файлах. -v Выдает все строки, за исключением содержащих образец. -w Ищет выражение как слово, как если бы оно было окружено метасимволами \< и \>.

grep --help

Использование: grep [ПАРАМЕТР]… ШАБЛОН [ФАЙЛ]… Поиск ШАБЛОНА в каждом ФАЙЛЕ или в стандартном вводе. По умолчанию, ШАБЛОН представляет собой простое регулярное выражение (BRE). Пример: grep -i "hello world" menu.h main.c Выбор типа регулярного выражения и его интерпретация: -E, --extended-regexp ШАБЛОН - расширенное регулярное выражение (ERE) -F, --fixed-regexp ШАБЛОН - строки фиксированной длины, разделённые символом новой строки -G, --basic-regexp ШАБЛОН - простое регулярное выражение (BRE) -P, --perl-regexp ШАБЛОН - регулярное выражения языка Perl -e, --regexp=ШАБЛОН использовать ШАБЛОН для поиска -f, --file=ФАЙЛ брать ШАБЛОН из ФАЙЛа -i, --ignore-case игнорировать различие регистра -w, --word-regexp ШАБЛОН должен подходить ко всем словам -x, --line-regexp ШАБЛОН должен подходить ко всей строке -z, --null-data строки разделяются байтом с нулевым значением, а не символом конца строки Разное: -s, --no-messages подавлять сообщения об ошибках -v, --revert-match выбирать не подходящие строки -V, --version напечатать информацию о версии и выйти --help показать эту справку и закончить работу --mmap для обратной совместимости, игнорируется Управление выводом: -m, --max-count=ЧИСЛО остановиться после указанного ЧИСЛА совпадений -b, --byte-offset печатать вместе с выходными строками смещение в байтах -n, --line-number печатать номер строки вместе с выходными строками --line-buffered сбрасывать буфер после каждой строки -H, --with-filename печатать имя файла для каждого совпадения -h, --no-filename не начинать вывод с имени файла --label=МЕТКА использовать МЕТКУ в качестве имени файла для стандартного ввода -o, --only-matching показывать только часть строки, совпадающей с ШАБЛОНОМ -q, --quiet, --silent подавлять весь обычный вывод --binary-files=ТИП считать, что двоичный файл имеет ТИП: binary, text или without-match. -a, --text то же что и --binary-files=text -I то же, что и --binary-files=without-match -d, --directories=ДЕЙСТВ как обрабатывать каталоги ДЕЙСТВИЕ может быть read (читать), recurse (рекурсивно) или skip (пропускать). -D, --devices=ДЕЙСТВ как обрабатывать устройства, FIFO и сокеты ДЕЙСТВИЕ может быть read или skip -R, -r, --recursive то же, что и --directories=recurse --include=Ф_ШАБЛОН обработать только файлы, подпадающие под Ф_ШАБЛОН --exclude=Ф_ШАБЛОН пропустить файлы и каталоги, подпадающие под Ф_ШАБЛОН --exclude-from=ФАЙЛ пропустить файлы, подпадающие под шаблон файлов из ФАЙЛА --exclude-dir=ШАБЛОН каталоги, подпадающие под ШАБЛОН, будут пропущены -L, --files-without-match печатать только имена ФАЙЛОВ без совпадений -l, --files-with-matches печатать только имена ФАЙЛОВ с совпадениями -c, --count печатать только количество совпадающих строк на ФАЙЛ -T, --initial-tab выравнивать табуляцией (если нужно) -Z, --null печатать байт 0 после имени ФАЙЛА Управление контекстом: -B, --before-context=ЧИС печатать ЧИСЛО строк предшествующего контекста -A, --after-context=ЧИС печатать ЧИСЛО строк последующего контекста -C, --context[=ЧИС] печатать ЧИСЛО строк контекста -ЧИСЛО то же, что и --context=ЧИСЛО --color[=КОГДА], --colour[=КОГДА] использовать маркеры для различия совпадающих строк; КОГДА может быть always (всегда), never (никогда) или auto (автоматически) -U, --binary не удалять символы CR в конце строки (MSDOS) -u, --unix-byte-offsets выдавать смещение, как-будто нет CR-ов (MSDOS) Вместо «egrep» предполагается запуск «grep -E». Вместо «fgrep» предполагается «grep -F». Запуск под именами «egrep» или «fgrep» лучше не выполнять. Когда не задан ФАЙЛ, или когда ФАЙЛ это -, то читается стандартный ввод. Если указано меньше, чем два файла, то предполагает -h. При нахождении совпадений кодом завершения программы будет 0, и 1, если нет.При возникновении ошибок, или если не указан параметр -q, кодом завершения будет 2. Об ошибках сообщайте по адресу Об ошибках в переводе сообщайте по адресу Домашняя страница GNU Grep: Справка по работе с программами GNU:


© 2024
exotop.ru - ExoTop - интернет и технологии