Команда LIKE
Команда LIKE задает поиск по определенному шаблону.
См. также команду NOT, которая делает отрицание (к примеру, так: NOT LIKE).
Синтаксис
Примеры
Все примеры будут по этой таблице workers, если не сказано иное:
| id айди |
name имя |
age возраст |
salary зарплата |
|---|---|---|---|
| 1 | Дима | 23 | 400 |
| 2 | Петя | 25 | 500 |
| 3 | Вася | 23 | 500 |
| 4 | Коля | 30 | 1000 |
| 5 | Иван | 27 | 500 |
| 6 | Кирилл | 28 | 1000 |
Пример
В данном примере команда LIKE найдет все записи, у которых имя заканчивается на ‘я’:
SQL запрос выберет следующие строки:
| id айди |
name имя |
age возраст |
salary зарплата |
|---|---|---|---|
| 2 | Пет я | 25 | 500 |
| 3 | Вас я | 23 | 500 |
| 4 | Кол я | 30 | 1000 |
Пример
Давайте выберем те записи, у которых возраст начинается с цифры 2, а затем идет еще один символ:
Кунг-фу стиля Linux: регулярные выражения
Если вы считаете, что умеете готовить, то может, вы знаете о том, как сделать суфле или пахлаву, а может — и не знаете. Но есть кое-что такое, чему вы, вероятно, научились, просто готовя разные блюда. Например, вы, скорее всего, можете вскипятить воду, можете правильно разбить яйцо, можете поджарить мясо. Если говорить о работе в Linux или Unix, то тут тоже можно сделать похожие наблюдения. Возможно, вы не знаете о том, как установить сервер Wayland, или о том, как написать модуль ядра. Но есть определённые базовые навыки, вроде работы с файлами или редактирования текстов, которые люди осваивают независимо от того, чем они занимаются, навыки, которые помогают им в самых разных ситуациях. Один из навыков, полезных в самых разных ситуациях, овладение которым часто вызывает определённые сложности, это — умение пользоваться регулярными выражениями. Многие программы используют их в качестве средства описания шаблонов поиска чего-либо. Обычно — для поиска данных в строках, например — в файлах с каким-то текстом.

Если вы не очень хорошо умеете пользоваться регулярными выражениями, знайте, что это легко исправить. Их не так уж и сложно изучить, кроме того — существуют замечательные инструменты, которые способны помочь при работе с регулярными выражениями. Сами регулярные выражения используются во многих утилитах. При этом везде используются одни и те же базовые синтаксические конструкции регулярных выражений. Источником путаницы, правда, являются особенности устройства регулярных выражений в разных средах. То, что выходит за рамки базовых синтаксических конструкций, в разных местах может различаться.
Разберём основы регулярных выражений, то, что нужно для того, чтобы хорошо их понимать и эффективно использовать.
Программы, в которых используются регулярные выражения
Возможно, первая программа, о которой вспоминают, когда говорят о регулярных выражениях, это — grep. Это — простая утилита, которая принимает регулярное выражение и имя файла (или несколько имён). Источником данных для неё может служить и стандартный поток ввода. В обычном режиме работы эта утилита выводит строки, в которых найдено совпадение с регулярным выражением. Это — простая, но мощная программа, она является одним из популярнейших инструментов командной строки. Именно поэтому я и решил построить примеры к этой статье на её основе.
Но grep — это далеко не единственная программа, использующая регулярные выражения. Среди других программ, в которых применяются регулярные выражения, можно отметить awk, sed, perl, разные редакторы, вроде Vim и emacs. Этот список можно продолжать ещё очень долго. Столь широкая распространённость регулярных выражений ведёт к тому, что их можно увидеть, например, в неких настройках программ, они встречаются даже в веб-приложениях, где используются для расширения возможностей этих приложений.
В различных системах может присутствовать не только grep, но и другие, похожие утилиты, вроде egrep. Например, в моей системе имеется команда egrep, которая представляет собой «обёртку» вокруг grep. Она вызывает grep с передачей этой утилите опции командной строки -E , что воздействует на вид регулярных выражений, с которыми работает grep. В результате тут я, если не отмечено иное, буду говорить именно о egrep.
Поиск строк по шаблонам и классы
Взгляните на следующий пример:
Эта команда просмотрит файл somefile.txt и найдёт следующие строки:
▍Точка — это универсальный символ
Строки со словом Dog при этом найдены не будут. Дело в том, что регулярные выражения, по умолчанию, чувствительны к регистру символов. Если бы этим все возможности регулярных выражений и ограничивались, тогда ничего особенно интересного в них бы не было. Но их возможности гораздо шире. Например, точка играет роль чего-то, напоминающего шаблон, соответствующий любому символу. Поэтому регулярное выражение d.g соответствует и строке dog , и строке dig (и, раз уж мы об этом говорим, строке d$g ).
▍Экранирование символов
Если точка — это «универсальный символ», то как тогда найти строки, в которых есть точка? Для этого можно воспользоваться экранированием символов с использованием обратной косой черты. Этот приём можно использовать в применении к любым специальным символам. В результате регулярное выражение d\.g найдёт строку d.g и ничего другого. Правда, тут стоит помнить о том, что символ обратной косой черты может иметь особый смысл в различных программах. Например, посмотрите на этот сеанс работы с egrep.
Использование обратной косой черты
Тут есть одна особенность. Оболочка интерпретирует последовательность символов \. как обычную точку. Она не считает обратную косую черту частью регулярного выражения, воспринимая её как экранирующий символ, используемый в самой оболочке. Для того чтобы, всё же, передать egrep конструкцию \. , нужно экранировать символ обратной косой черты ещё одним таким же символом ( \\ ). Именно это и сделано во втором примере. Экранирование специальных символов может оказаться непростой задачей, конкретные действия зависят от используемой оболочки. Если вы применяете bash, то вам, возможно, достаточно будет заключить регулярное выражение в одинарные или двойные кавычки. Но даже при таком подходе остаются актуальными правила, касающиеся обратной косой черты.
▍Классы символов
Иногда того, кто использует регулярные выражения, не интересует один заранее заданный символ. Но его при этом не устроит и поиск любого символа. В таких ситуациях в дело вступают классы символов. Например:
Эта команда найдёт строки вроде X000V и Z123V . Этот приём часто используют для того чтобы сделать поиск нечувствительным к регистру символов (например, используя конструкции вроде [aA] или [a-zA-Z] ).
Кроме того, можно описывать классы символов, которые не должны содержаться в искомых строках. Делается это с использованием символа ^ . Например, класс [^XYZ] соответствует любому символу кроме X , Y и Z . Если нужно найти тире ( — ), то этот знак должен идти в начале группы. А вот если нужно найти символ ^ — его не надо ставить в начало группы. Так как порядок символов в группе не играет роли при её обработке, проблем это не вызовет. В результате, например, если нас интересуют все цифры, а так же символы — и ^ , то соответствующее регулярное выражение будет выглядеть так:
Повторы
Мы уже знаем о том, как найти слова dog , dig , dug и d$g . Это очень хорошо, но лишь этим возможности регулярных выражений не ограничиваются. А именно, при использовании регулярных выражений можно описывать последовательности повторяющихся символов. Можно сделать и так, чтобы некий символ был бы необязательным. Например, вот регулярное выражение, которое найдёт и слово bar , и слово bear : be?ar .
Часто надо сделать так, чтобы некий шаблон мог бы присутствовать в находимых строках в одном экземпляре, но мог бы и полностью в них отсутствовать. Может понадобиться и поиск повторяющихся символов, а заодно и выявление их полного отсутствия. Иногда надо, чтобы регулярное выражение реагировало бы на нечто, имеющееся в строке в единственном экземпляре или повторяющееся несколько раз. Предположим, что нужно найти в файле некоего лога числа с десятичной точкой, перед которыми может присутствовать дефис, символизирующий знак «минус», а может и не присутствовать. В этой ситуации можно использовать конструкцию -?[0-9]+\.?[0-9]* . Для того чтобы лучше понимать подобные конструкции, полезным может оказаться представление их в виде диаграмм.
Графическое представление регулярного выражения (создано с помощью Regexper )
Этому шаблону будут соответствовать числа -25.2 , 33. , 17.125 . Знак + указывает на то, что в строке должна быть, как минимум, одна цифра, но их может быть и больше. Символ * соответствует любому количеству цифр, в том числе — и нулевому. Обратите внимание на то, что символ десятичной точки нуждается в экранировании. У этого регулярного выражения есть одна интересная особенность. Оно будет работать и без экранирования символа десятичной точки. Ведь точка соответствует любому символу. Но при таком подходе найдено будет и нечто вроде 14X2 , то есть, в нашем случае, неправильно оформленное число.
▍Продвинутое описание повторов
В более продвинутых регулярных выражениях для описания повторов можно пользоваться фигурными скобками, указывая в них то, сколько раз может повторяться шаблон. Некоторые инструменты требуют экранирования символов фигурных скобок. При работе с grep экранировать их не нужно. То есть, например, если нужно найти четыре буквы, записанные в нижнем регистре, можно воспользоваться конструкцией [a-z] <4>.
Безусловно, то же самое можно описать и так: [a-z][a-z][a-z][a-z] . Применение фигурных скобок лишь ускоряет ввод соответствующих конструкций. В фигурных скобках, кроме того, можно указывать диапазон количества повторов, задавая его нижнюю и верхнюю границы. Например — так: [a-z] <2,4>. Это соответствует последовательностям длиной от двух до четырёх символов. Это — то же самое, что и [a-z][a-z][a-z]?[a-z]? .
▍В разных программах обработка повторов различается
Для grep достаточно факта нахождения совпадения с регулярным выражением. При работе с некоторыми другими инструментами в расчёт принимается совпадение с наибольшим или наименьшим количеством символов. Например, регулярное выражение abc* , применённое к строке, содержащей abccccc , может обнаружить только символы ab , а может и найти совпадение со всей этой последовательностью символов. Это зависит от конкретного инструмента (и иногда — от настроек этого инструмента, например — от опций командной строки). Но об этом стоит помнить. Разные инструменты работают по-разному в деле обработки множественных совпадений. Например, при применении шаблона X к строке XyyX может быть найден только первый X , но могут быть найдены и оба символа. Но для grep, опять же, это значения не имеет. Этот инструмент интересует нахождение в строке хотя бы одного совпадения с регулярным выражением.
Привязка шаблона к началу и к концу строки
Возможно, вы обратили внимание на то, что в вышеприведённых примерах совпадение с шаблоном может быть найдено в любой части строки. Но, если нужно, можно привязать шаблон к началу строки, воспользовавшись символом ^ , или к концу строки — с помощью символа $ . Например, такая конструкция поможет найти пустые строки: ^ *$. А если нужно, чтобы подобные строки начинались бы с символа табуляции, можно поступить так: ^[ \t]*$ .
Последовательность \t , как и в языке C, означает знак табуляции. В зависимости от того, какой именно инструмент используется, в вашем распоряжении могут оказаться и другие особые символы. Вот, например, как искать строки, первым непробельным символом которых является % : ^[ \t]*% .
Группировка
Существует несколько способов группировки регулярных выражений. Можно использовать скобки (правда, некоторые инструменты требуют их экранирования при использовании их для группировки шаблонов). Вот пример:
Такое регулярное выражение будет искать строки, начинающиеся с буквы a , за которой идёт символ d или последовательность символов bcd .

Графическое представление регулярного выражения (создано с помощью Regexper )
Это — не то же самое, что ab?c?d , так как такое регулярное выражение отреагирует на последовательность символов acd . Кроме того, в регулярных выражениях можно использовать символ | , играющий роль оператора ИЛИ . Например, конструкция a|b найдёт символ a или символ b , что не особенно отличается от возможностей конструкции [ab] .
Но если объединить эту возможность с группировкой — может получиться нечто весьма полезное. Например, конструкция вида (dog)|(cat) способна найти и dog , и cat . В некоторых программах группировка способна помочь в выделении интересующих разработчика фрагментов кода, или может позволить выполнять продвинутую замену текстов. Например, в некоторых программах можно выполнить поиск с использованием регулярного выражения id=([0-9])+ , а в строке замены можно использовать конструкцию \1 для того чтобы сослаться на любое число, совпавшее с выражением, указанным в скобках. То, как именно это будет выглядеть, зависит от конкретной программы. Например, в некоторых программах может применяться нечто вроде &1 .
В чём польза регулярных выражений? Зачем их изучать?
О самих регулярных выражениях можно говорить ещё очень долго. Но сейчас давайте немного от них отвлечёмся и поговорим о том, какую пользу они могут принести тому, кто умеет с ними работать. Предположим, у нас имеется лог-файл, в котором содержится масса температурных данных в градусах Цельсия. В этом файле есть и другие данные. Но все температурные данные представлены в виде чисел, за которыми идёт пробел и буква C . В результате температурные показатели могут выглядеть, например, как -22 C и 13.5 C .
Преобразовать эти числа к необходимому виду можно с помощью чего-то вроде awk. Не хочу тут вдаваться в подробности об awk, отмечу лишь то, что тут имеется функция match и функция gensub , которая позволяет осуществлять поиск и замену строковых данных с использованием регулярных выражений. Кроме того, программа позволяет фильтровать строки с использованием правил, которые представляют собой регулярные выражения, ограниченные символами косой черты. Взгляните на этот код:
В первой строке кода осуществляется поиск текстов, содержащих пробел и букву C в конце строки. Подпрограмма match получает число в matchres[1] . При таком подходе она сочтёт подходящей и бессмыслицу вроде -…C , но мы можем предположить, что в наших данных ничего такого нет. Возможно, ситуацию улучшит использование такого регулярного выражения: -?[0-9]\.?[0-9]* (правда, обратите внимание на то, что для использования такого регулярного выражения с grep, из-за использования в его начале символа — , нужно будет воспользоваться опцией -e ). Преобразование выполняет функция gensub . Как видите, для решения задачи понадобилось немало знаний о регулярных выражениях.
Варианты регулярных выражений
К сожалению, между способами использования регулярных выражений существуют небольшие различия. Вот что однажды сказал по этому поводу Дональд Кнут: «Я определяю UNIX, как 30 определений регулярных выражений, живущих под одной крышей».
Я уже говорил о некоторых из этих различий. Например, некоторые реализации регулярных выражений воспринимают скобки как группировочные символы в том случае, если они не экранированы. А другие, при таком их использовании, требуют их экранировать. Иначе скобки будут восприниматься как обычные символы.
Часто в регулярных выражениях используются сокращённые конструкции для описания чего-то вроде цифр и пробельных символов. Это полезная возможность, так как она повышает переносимость регулярных выражений. Например, конструкция [:digit:] является заменой для [0-9] . В некоторых программах для той же цели используются особые управляющие символы, вроде \d . Здесь можно найти таблицу, в которой имеются описания распространённых систем регулярных выражений.
Инструменты для отладки регулярных выражений
Собственно говоря, это — всё, что нужно знать о регулярных выражениях для начала работы с ними. Если вы хотите отлаживать регулярные выражения в интерактивном режиме, то знайте, что существует множество хороших инструментов, направленных на решение этой задачи. Ещё можно строить схемы регулярных выражений. Это помогает лучше понимать их смысл.
Возможно, вам пригодится библиотека регулярных выражений, из которой можно, так сказать, что-нибудь позаимствовать. А если вы хотите изучать регулярные выражения в игровой форме — можете заглянуть сюда и сюда.
Команда grep и регулярные выражения в Linux
В предыдущих статьях мы рассмотрели набор фильтров, которые помогают управлять данными. В этой статье мы рассмотрим еще один фильтр, который в сочетании с так называемыми регулярными выражениями является очень мощным инструментом.
Поначалу в регулярных выражениях бывает трудно разобраться, поэтому не волнуйтесь, если что-то покажется непонятным. Просто попробуйте отложить материал на несколько дней и снова прочитать его, параллельно эксперементируя в командой строке. Со второго раз все начнет обретать смысл. Регулярные выражения — это не очень просто, так что не сдавайтесь.
Что такое egrep
egrep — это команда, которая ищет заданный шаблон в файле и выводит каждую строчку, содержащую этот шаблон.
Это расширение команды grep. Буква e там появилась от аналогичной команды в текстовом редакторе под названием ed.
У команды egrep множество параметров, которые изменяют ее поведение, поэтому советуем самостоятельно просмотреть ее man-страницу. Например, параметр -v заставляет grep печатать каждую строку, которая не соответствует шаблону.
В приведенных ниже примерах мы будем использовать файл mysampledata.txt, с которым мы эксперементировали в статье про фильтры. Напомним, как он выглядит:
Допустим, мы хотим найти каждую строчку, в которой содержится mellon.
Обычно egrep выводит всю строчку, которая содержит заданный шаблон. Обратите вниманием, что мы ищем не слово, а строку — то есть набор символов.
Примечание. Заметьте, что мы заключили шаблон в кавычки. Обычно это не обязательно, но безопаснее выработать привычку всё-таки использовать их. Кавычки необходимы, если шаблон содержит символы, которые имеют специальное назначение в командной строке.
Теперь представьте, что нам нужно знать не только, в каких строках есть заданные шаблоном подстроки, но и номер этих строчек в файле. Для этого понадобится параметр -n .
Если нам не нужны строчки, в которых нашлась заданная подстрока, а нужно только количество таких строчек, можно использовать параметр -c .
Что такое регулярные выражения
Регулярные выражения (regular expressions) похожи на шаблоны подстановки (wildcards), о которых мы уже говорили. Однако это гораздо более мощный инструмент, который в разы расширяет возможности поиска текста в файлах. Регулярки обычно используют для идентификации и управления определенными частями данных. Например, если нужно найти каждую строку, содержащую адрес электронной почты или URL в некотором наборе данных.
Мы будем изучать регулярные выражения на примере команды grep , но регулярки можно использовать и с большинством других команд: например, sed и vi , о которых вы говорили в предыдущих статьях. Во многих языках программирования регулярные выражения тоже присутствуют.
Примечание. Символы, которые используются в регулярных выражениях, совпадают с символами подстановки. Однако их поведение несколько отличается. Помните об этом и не путайте функции регулярных выражений и шаблонов подстановки.
Вот список основных символов, используемых в регулярных выражениях:
- . (точка) — один любой символ.
- ? (знак вопроса) — указывает, что предыдущий символ может встречаться 0 или 1 раз.
- * (звездочка) — указывает, что предыдущий символ может повторяться 0 или больше раз.
- + (плюс) — указывает, что предыдущий символ должен повториться один или больше раз.
— указывает, что предыдущий символ должен повториться ровно n раз. — указывает, что предыдущий символ может повторяться от n до m раз. - [agd] — любой из указанных в квадратных скобках символов.
- [^agd] — любой символ, кроме указанных в квадратных скобках.
- [c-f] — любой символ из указанного диапазона. В этом случае: c, d, e или f.
- () — группирует нескольких символов, чтобы они вели себя как один.
- | (вертикальная черта) — логическая операция ИЛИ.
- ^ (каретка) — указывает на начало строки.
- $ (знак доллара)— указывает на конец строки.
Давайте разберемся, как работают некоторые из этих символов на примерах.
Пример 1. Выводим все строчки с двумя или более гласными
Здесь <2,>применяется к предыдущему элементу, который является диапазоном.
Пример 2. Выводим все строчки с цифровой 2, если она не стоит в конце
В этом примере + применяется к . (любой символ) — так мы даем терминалу понять, что за 2 обязятельно должно что-то идти. То есть выполняем требование, что 2 не стоит в конце строчки.
Пример 3. Выводим все строчки с цифровой 2 на конце
Теперь всё наоборот: нужно, чтобы после 2 на строчке ничего больше не было. Для этого используем символ $ , который указывает на конец строки.
Пример 4. Выводим все строчки, в которых содержится ‘is’ или ‘go’, или ‘or’
Пример 5. Выводим все строчки, которые начинаются с букв в промежутке от A до K
Что делать, если что-то не получается
В процессе обучения вы часто будете делать ошибки в шаблонах. Помните, что вы всегда можете легко вернуться назад и попробовать еще раз. Просто нажмите стрелку вверх на клавиатуре, чтобы просмотреть последние введенные команды и изменить их.
Если что-то не получается, попробуйте сделать это:
• Проверьте, нет ли опечаток. Вы могли просто перепутать какой-то символ.
• Перечитайте, что вы написали. Возможно, вы думали, что оператор делает одно, а на самом деле он работает иначе. При повторном чтении вы заметите это.
• Разбейте шаблон на отдельные части и протестируйте каждую из них по отдельности. Это поможет понять, какие части правильные, а какие нужно подкорректировать.
• Изучите, как работает grep с текущим шаблоном. Даже если результат не такой, каким вы ожидали его увидеть, из этого все равно можно извлечь урок. Постарайтесь понять, почему получается именно такой результат. Так вы поймете, что нужно попробовать изменить, чтобы приблизиться к желаемому результату.
Совет. Попробуйте Debuggex — это онлайн-сервис, который позволяет экспериментировать с регулярными выражениями и визуализировать их поведение. Так вы лучше поймете, как они работают.
Что нужно запомнить
Команды
egrep
Выводит строчки, которые соответствуют определенному шаблону.
Практические задания
Для начала создайте файл с данными, похожий на наш файл-образец mysampledata.txt.
1. Попробуйте прогнать задания из примеров 1–5 на собственном файле.
2. Просмотрите страницу man для egrep и попробуйте хотя бы 2 разных параметра для них.
Как искать в Vim / Vi
В этой статье описывается, как выполнять поисковые операции в Vim / Vi.
Vim или его предшественник Vi предустановлен в macOS и большинстве дистрибутивов Linux. Поиск текста — одна из самых распространенных задач при работе с файлами. Знание основ Vim может быть очень полезным, когда вы сталкиваетесь с ситуацией, когда ваш любимый редактор недоступен.
Базовый поиск
Для поиска в Vim вы должны быть в обычном режиме. Когда вы запускаете редактор Vim, вы находитесь в этом режиме. Чтобы вернуться в нормальный режим из любого другого режима, просто нажмите клавишу Esc.
Vim позволяет быстро находить текст с помощью / (косая черта) и ? (знак вопроса) команды.
Для поиска вперед нажмите / а для поиска назад нажмите ? , введите шаблон поиска и нажмите Enter чтобы запустить поиск:
Важно отметить, что команда поиска ищет шаблон как строку, а не целое слово. Если, например, вы искали «gnu», поиск совпадет с тем, что «gnu» встроено в слова большего размера, такие как «cygnus» или «magnum».
Нажмите n для поиска следующего вхождения или N в верхнем регистре для поиска в обратном направлении.
Основные шаги для выполнения поиска в Vim следующие:
- Нажмите / .
- Введите шаблон поиска.
- Нажмите Enter чтобы выполнить поиск.
- Нажмите n чтобы найти следующее вхождение, или N чтобы найти предыдущее вхождение.
Искать слово целиком
Для поиска всего слова начните поиск, нажав / или ? , введите < чтобы отметить начало слова, введите шаблон поиска, введите > чтобы отметить конец слова, и нажмите Enter чтобы выполнить поиск.
Например, для поиска «gnu» вы должны использовать /<work> :
Искать в текущем слове
Вы также можете выполнить поиск целого слова, переместив курсор на слово и нажав * (звездочка) для поиска вперед или # (решетка) для поиска в обратном направлении. Чтобы найти следующее совпадение, снова нажмите * или # .
История поиска
Vim отслеживает все операции поиска, выполненные вами в текущем сеансе. Чтобы просмотреть историю поиска, нажмите / или ? и используйте клавиши со стрелками вверх / вниз, чтобы найти предыдущую операцию поиска. Чтобы запустить поиск, просто нажмите Enter . Вы также можете отредактировать шаблон поиска перед выполнением операции.
Чувствительность к регистру
По умолчанию в результатах поиска учитывается регистр; поиск «GNU» не будет соответствовать «Gnu».
Чтобы игнорировать регистр :set ignorecase или :set ic в командной строке Vim. Вы также можете установить регистр игнорирования как вариант по умолчанию, добавив команду в ваш файл
Чтобы вернуться в режим совпадения регистра, введите :set noignorecase или :set noic .
Другой способ принудительно игнорировать регистр — добавить c после шаблона поиска. Например, /Linuxc выполняет поиск без учета регистра. Верхний регистр C после шаблона приводит к поиску совпадения по регистру.
Выводы
Для поиска в Vim / Vi введите / или ? , введите шаблон поиска и нажмите Enter .