Использование регулярных выражений (regex) в Linux. Регулярные выражения Linux Linux grep регулярные выражения

Утилита 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

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

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

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

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!

Об этом самоучителе

Добро пожаловать в «Азы администрирования», второе из четырех обучающих руководств, разработанных чтобы подготовить вас к экзамену 101 в Linux Professional Institute. В данной части мы рассмотрим как использовать регулярные выражения для поиска текста в файлах по шаблонам. Затем, вы познакомитесь со «Стандартом иерархии файловой системы» (Filesystem Hierarchy Standard или сокр. FHS), также мы покажем вам как находить нужные файлы в вашей системе. После чего, вы узнаете как получить полный контроль над процессами в Linux, запуская их в фоновом режиме, просматривая список процессов, отсоединяя их от терминала, и многое другое. Далее последует быстрое введение в конвейеры, перенаправления и команды обработки текста. И наконец, мы познакомим вас с модулями ядра Linux.

В частности эта часть самоучителя (Часть 2) идеальна для тех, кто уже имеет неплохие базовые знания bash и хочет получить качественное введение в основные задачи администрирования Linux. Если в Linux вы новичок, мы рекомендуем вам сперва закончить первую часть данной серии практических руководств . Для некоторых, большая часть данного материала будет новой, более опытные же пользователи Linux могут счесть его отличным средством подвести итог своим базовым навыкам администрирования.



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

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

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

Регулярное выражение (по англ. regular expression, сокр. «regexp» или «regex», в отечестве иногда зовется «регулярка» - прим. пер.) - это особый синтаксис используемый для описания текстовых шаблонов. В Linux-системах регулярные выражения широко используются для поиска в тексте по шаблону, а также для операций поиска и замены на текстовых потоках.

В сравнении с глоббингом

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

Простая подстрока

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

$ grep bash /etc/passwd
operator:x:11:0:operator:/root:/bin/bash root:x:0:0::/root:/bin/bash ftp:x:40:1::/home/ftp:/bin/bash

Выше, первый параметр для grep, это regex; второй - имя файла. grep считывал каждую строчку из /etc/passwd и прикладывал на нее простую regex-подстроку «bash» в поисках совпадения. Если совпадение обнаруживалось, то grep выводил всю строку целиком; в противном случае, строка игнорировалась.

Понимание простой подстроки

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

  • /tmp (поиск строки /tmp)
  • "\" (поиск строки )
  • "\*funny\*" (поиск строки *funny*)
  • «ld\.so» (поиск строки ld.so)

Метасимволы

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

$ grep dev.sda /etc/fstab
/dev/sda3 / reiserfs noatime,ro 1 1 /dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0 #/dev/sda4 /mnt/extra reiserfs noatime,rw 1 1

В этом примере текст dev.sda не появляется буквально ни в одной из строчек из /etc/fstab . Однако, grep сканирует его не буквально по строке dev.sda, а по dev.sda шаблону. Запомните, что "." будет соответствовать любому единичному символу. Как вы видите, метасимвол "." функционально эквивалентен тому, как работает метасимвол "?" в glob-подстановках.

Использование

Если мы хотим задать символ конкретнее, чем это делает ".", то можем использовать [ и ] (квадратные скобки), чтобы указать подмножество символов для сопоставления:

$ grep dev.sda /etc/fstab
/dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0

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

Использование [^]

Вы можете обратить значение квадратных скобок поместив ^ сразу после [. В этому случае скобки будут соответствовать любому символу который НЕ перечислен внутри них. И опять, заметьте что [^] мы используем с регулярными выражением, а [!] с glob:

$ grep dev.hda[^12] /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1 #/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1

Отличающийся синтаксис

Очень важно отметить, что синтаксис внутри квадратных скобок коренным образом отличается от остальной части регулярного выражения. К примеру, если вы поместите "." внутрь квадратных скобок, это позволит квадратным скобкам совпадать с "." буквально, также как 1 и 2 в примере выше. Для сравнения, "." помещенная вне квадратных скобок, будет интерпретирована как метасимвол, если не приставить "\". Мы можем получить выгоду из данного факта для вывода строк из /etc/fstab которые содержат строку dev.sda, как она записана:

$ grep dev[.]sda /etc/fstab

Также, мы могли бы набрать:

$ grep "dev\.sda" /etc/fstab

Эти регулярные выражения вероятно не удовлетворяют ни одной строчке из вашего /etc/fstab файла.

Матасимвол *

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

  • ab*c совпадает с «abbbbc», но не с «abqc» (в случае glob-подстановки, обе строчки будут удовлетворять шаблону. Вы уже поняли почему?)
  • ab*c совпадает с «abc», но не с «abbqbbc» (опять же, при glob-подстановке, шаблон сопоставим с обоими строчками)
  • ab*c совпадает с «ac», но не с «cba» (в случае глоббинга, ни «ac», ни «cba» не удовлетворяют шаблону)
  • b*e совпадает с «bqe» и с «be» (glob-подстановке удовлетворяет «bqe», но не «be»)
  • b*e совпадает с «bccqqe», но не с «bccc» (при глоббинге шаблон точно так же совпадет с первым, но не со вторым)
  • b*e совпадает с «bqqcce», но не с «cqe» (так же и при glob-подстановке)
  • b*e удовлетворяет «bbbeee» (но не в случае глоббинга)
  • .* сопоставим с любой строкой (glob-подстановке удовлетворяют только строки начинающиеся с ".")
  • foo.* совпадет с любой подстрокой начинающийся с «foo» (в случае glob-подстановки этот шаблон будет совпадать со строками, начинающимися с четырех символов «foo.»)

Итак, повторим для закрепления: строчка «ac» подходит под регулярное выражение «ab*c» потому, что звездочка также позволяет повторение предшествующего выражения (b) ноль раз. И опять, ценно отметить для себя, что метасимвол * в регулярках интерпретируется совершенно иначе, нежели символ * в glob-подстновках.

Начало и конец строки

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

$ grep ^# /etc/fstab

#

Полнострочные регулярки

^ и $ можно комбинировать, для сопоставлений со всей строкой целиком. Например, нижеследующая регулярка будет соответсвовать строкам начинающимся с символа #, а заканчивающимся символом ".", при произвольном количестве символов между ними:

$ grep "^#.*\.$" /etc/fstab
# /etc/fstab: static file system information.

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

Об авторах

Daniel Robbins

Дэниэль Роббинс - основатель сообщества Gentoo и создатель операционной системы Gentoo Linux. Дэниэль проживает в Нью-Мехико со свой женой Мэри и двумя энергичными дочерьми. Он также основатель и глава Funtoo , написал множество технических статей для IBM developerWorks , Intel Developer Services и C/C++ Users Journal.

Chris Houser

Крис Хаусер был сторонником UNIX c 1994 года, когда присоединился к команде администраторов университета Тэйлора (Индиана, США), где получил степень бакалавра в компьютерных науках и математике. После он работал во множестве областей, включая веб-приложения, редактирование видео, драйвера для UNIX и криптографическую защиту. В настоящий момент работает в Sentry Data Systems. Крис также сделал вклад во множество свободных проектов, таких как Gentoo Linux и Clojure, стал соавтором книги The Joy of Clojure .

Aron Griffis

Эйрон Гриффис живет на территории Бостона, где провел последнее десятилетие работая в Hewlett-Packard над такими проектами, как сетевые UNIX-драйвера для Tru64, сертификация безопасности Linux, Xen и KVM виртуализация, и самое последнее - платформа HP ePrint . В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».

Одна из наиболее полезных и многофункциональных команд в терминале 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 настолько полезна, многофункциональна и проста в употреблении, что, однажды познакомившись с ней, невозможно представить себе работу без нее.

Одна из наиболее полезных и многофункциональных команд в терминале Linux – команда «grep». Grep – это акроним, который расшифровывается как «global regular expression print» (то есть, «искать везде соответствующие регулярному выражению строки и выводить их»). Это значит, что grep можно использовать для того, чтобы просмотреть, соответствуют ли вводимые данные заданным шаблонам.

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

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

Основы использования

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

В качестве примера можно использовать grep для поиска строк, содержащих слово «GNU» в версии 3 GNU General Public License на системе Ubuntu.

cd /usr/share/common-licenses
grep "GNU" GPL-3
GNU GENERAL PUBLIC LICENSE





13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
...

Первый аргумент, «GNU», является искомым шаблоном, а второй аргумент, «GPL-3», является входным файлом, который нужно найти.

В результате будут выведены все строки, содержащие текстовый шаблон. В некоторых дистрибутивах Linux искомый шаблон будет выделен в выведенных строках.

Общие опции

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

При необходимости игнорировать регистр параметра поиска и искать как прописные, так и строчные вариации шаблона, можно использовать утилиты «-i» или «—ignore-case».

Для примера можно использовать grep для поиска в том же файле слова «license», написанного верхним, нижним или смешанным регистром.

grep -i "license" GPL-3
GNU GENERAL PUBLIC LICENSE
of this license document, but changing it is not allowed.
The GNU General Public License is a free, copyleft license for
The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to


"This License" refers to version 3 of the GNU General Public License.
"The Program" refers to any copyrightable work licensed under this
...
...

Как можно видеть, выведенные результаты содержат «LICENSE», «license», and «License». Если бы в файле был экземпляр «LiCeNsE», он также был бы выведен.
При необходимости найти все строки, которые не содержат указанный шаблон, можно использовать флаги «-v» или «—invert-match».

Для примера можно применить следующую команду для поиска в лицензии BSD всех строк, которые не содержат слово «the»:

grep -v "the" BSD
All rights reserved.
Redistribution and use in source and binary forms, with or without
are met:
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS"" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

Как можно видеть, последние две строки были выведены как не содержащие слова «the», поскольку команда «ignore case» не была использована.

Всегда полезно знать номера строк, в которых были обнаружены совпадения. Их можно узнать при помощи флагов «-n» или «—line-number» .

Если применить данный флаг в предыдущем примере, будет выведен следующий результат:

grep -vn "the" BSD
2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13: may be used to endorse or promote products derived from this software
14: without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS"" AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

Теперь можно сослаться на номер строки при необходимости внести изменения в каждой строке, которая не содержит «the».

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

Как было сказано во вступлении, grep расшифровывается как «global regular expression print». Регулярное выражение – это текстовая строка, которая описывает определенный шаблон поиска.

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

Буквенные совпадения

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

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

Шаблоны, точно соответствующие заданным символам, называются «буквенными», поскольку они соответствуют шаблону побуквенно, символ в символ.

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

Совпадения анкоров

Анкоры – это специальные символы, которые указывают местонахождение в строке необходимого совпадения.

К примеру, можно указать, что при поиске нужны только строки, содержащие слово «GNU» в самом начале. Для этого нужно использовать анкор «^» перед буквенной строкой.

В этом примере выведены только строки, содержащие в самом начале слово «GNU».

grep "^GNU" GPL-3
GNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published

Аналогично, анкор «$» можно использовать после буквенной строки, чтобы указать, что совпадение действительно, только если искомая строка символов находится в конце текстовой строки.

В следующем регулярном выражении выведены только те строки, которые содержат «and» в конце:

grep "and$" GPL-3
that there is no warranty for this free software. For both users" and
The precise terms and conditions for copying, distribution and


alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and

Совпадение любого символа

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

К примеру, при необходимости найти совпадения, содержащие два символа и затем последовательность «cept», нужно использовать следующий шаблон:

grep "..cept" GPL-3
use, which is precisely where it is most unacceptable. Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the

form of a separately written license, or stated as exceptions;
You may not propagate or modify a covered work except as expressly
9. Acceptance Not Required for Having Copies.
...
...

Как можно видеть, в результатах выведены слова «accept» and «except», а также вариации этих слов. Шаблон также совпал бы с последовательностью «z2cept», если бы такая была в тексте.

Выражения в скобках

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

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

grep "to" GPL-3
your programs, too.

Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.

Corresponding Source from a network server at no charge.
...
...

Как можно видеть, обе вариации были найдены в файле.

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

В данном примере используется шаблон «.ode», с которым не должна совпадать последовательность «code».

grep "[^c]ode" GPL-3
1. Source Code.
model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:

Стоит заметить, что вторая выведенная строка содержит слово «code». Это не ошибка регулярного выражения или команды grep.

Вернее, эта строка была выведена, потому что она также содержит соответствующую шаблону последовательность «mode», найденную в слове «model». То есть, строка была выведена потому, что в ней было обнаружено совпадение с шаблоном.

Еще одна полезная функция скобок – возможность указать диапазон символов вместо того, чтобы отдельно вводить каждый символ.

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

grep "^" GPL-3
GNU General Public License for most of our software; it applies also to

License. Each licensee is addressed as "you". "Licensees" and


System Libraries, or general-purpose tools or generally available free
Source.

...
...

В связи с некоторыми наследственными проблемами сортировки, для более точного результата лучше использовать классы символов стандарта POSIX вместо диапазона символов, использованного в примере выше.
Существует множество классов символов, не охваченных данным руководством; к примеру, чтобы выполнить ту же процедуру, что и в примере выше, можно использовать класс символов «[:upper:]» в скобках.

grep "^[[:upper:]]" GPL-3
GNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License. Each licensee is addressed as "you". "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
...
...

Шаблон повторения (0 или больше раз)

Одним из наиболее часто используемых метасимволов является символ «*», что означает «повторить предыдущий символ или выражение 0 или больше раз».

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

grep "(*)" GPL-3

distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
(including a physical distribution medium), accompanied by the
(including a physical distribution medium), accompanied by a
place (gratis or for a charge), and offer equivalent access to the
...
...

Как избежать метасимволов

Иногда может понадобиться искать буквальную точку или буквальную открытую скобку. Поскольку данные символы имеют определенное значение в регулярных выражениях, необходимо «избегать» их, говоря команде grep, что в данном случае использовать их особое значение не нужно.

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

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

grep "^.*\.$" GPL-3
Source.
License by making exceptions from one or more of its conditions.
License would be to refrain entirely from conveying the Program.
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
SUCH DAMAGES.
Also add information on how to contact you by electronic and paper mail.

Расширенные регулярные выражения

Команду Grep можно также использовать с расширенным языком регулярных выражений при помощи флага «-E» или же вызывая команду «egrep» вместо «grep».

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

Группирование

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

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

grep "\(grouping\)" file.txt
grep -E "(grouping)" file.txt
egrep "(grouping)" file.txt

Приведенные выше выражения являются эквивалентами.

Чередование

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

Для обозначения чередования используется символ вертикальной черты «|». Чередование часто применяется в группировании для того, чтобы указать, что один из двух или более возможных вариантов должен рассматриваться как совпадение.

В данном примере нужно найти «GPL» или «General Public License»:

grep -E "(GPL|General Public License)" GPL-3
The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price. Our General Public Licenses are designed to make sure that you
Developers that use the GNU GPL protect your rights with two steps:
For the developers" and authors" protection, the GPL clearly explains
authors" sake, the GPL requires that modified versions be marked as
have designed this version of the GPL to prohibit the practice for those
...
...

Чередование можно использовать для выбора между двумя и более вариантами; для этого нужно ввести остальные варианты в группу отбора, отделяя каждый при помощи символа вертикальной черты «|».

Кванторы

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

Чтобы указать совпадение символа 0 или больше раз, можно использовать символ «?». Он сделает предыдущий символ или ряд символов, по сути, необязательными.

В данном примере при помощи внесения последовательности «copy» в факультативную группу выведены совпадения «copyright» и «right»:

grep -E "(copy)?right" GPL-3
Copyright (C) 2007 Free Software Foundation, Inc.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
"Copyright" also means copyright-like laws that apply to other kinds of
...
...

Символ «+» ищет совпадения выражений 1 или больше раз. Он работает почти как символ «*», но при использовании «+» выражение должно совпасть хотя бы 1 раз.

Приведенное ниже выражение ищет совпадения строки «free» плюс 1 или больше символов, которые не являются пробельными:

grep -E "free[^[:space:]]+" GPL-3
The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
When we speak of free software, we are referring to freedom, not
have the freedom to distribute copies of free software (and charge for

freedoms that you received. You must make sure that they, too, receive
protecting users" freedom to change the software. The systematic
of the GPL, as needed to protect the freedom of users.
patents cannot be used to render the program non-free.

Количество повторений совпадений

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

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

grep -E "{3}" GPL-3
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
receive it, in any medium, provided that you conspicuously and
give under the previous paragraph, plus a right to possession of the
covered work so as to satisfy simultaneously your obligations under this
При необходимости найти все слова, состоящие из 16-20 символов, используйте следующее выражение:
grep -E "[[:alpha:]]{16,20}" GPL-3
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
c) Prohibiting misrepresentation of the origin of that material, or

Выводы

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

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

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

Tags: ,
  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то