Regex регулярные выражения bash. Пять примеров использования grep. Синтаксические аспекты языка "Баша"

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

Добро пожаловать в «Азы администрирования», второе из четырех обучающих руководств, разработанных чтобы подготовить вас к экзамену 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 . В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».

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:

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

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

  • Проверка ввода текста;
  • Поиск и замена текста в файле;
  • Пакетное переименование файлов;
  • Взаимодействие с сервисами, таким как Apache;
  • Проверка строки на соответствие шаблону.

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

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

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

  • обычные буквы;
  • метасимволы.

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

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

обычный_символ спецсимвол_оператор

спецсимвол_замены спецсимвол_оператор

  • \ - с обратной косой черты начинаются буквенные спецсимволы, а также он используется если нужно использовать спецсимвол в виде какого-либо знака препинания;
  • ^ - указывает на начало строки;
  • $ - указывает на конец строки;
  • * - указывает, что предыдущий символ может повторяться 0 или больше раз;
  • + - указывает, что предыдущий символ должен повторится больше один или больше раз;
  • ? - предыдущий символ может встречаться ноль или один раз;
  • {n} - указывает сколько раз (n) нужно повторить предыдущий символ;
  • {N,n} - предыдущий символ может повторяться от N до n раз;
  • . - любой символ кроме перевода строки;
  • - любой символ, указанный в скобках;
  • х|у - символ x или символ y;
  • [^az] - любой символ, кроме тех, что указаны в скобках;
  • - любой символ из указанного диапазона;
  • [^a-z] - любой символ, которого нет в диапазоне;
  • \b - обозначает границу слова с пробелом;
  • \B - обозначает что символ должен быть внутри слова, например, ux совпадет с uxb или tuxedo, но не совпадет с Linux;
  • \d - означает, что символ - цифра;
  • \D - нецифровой символ;
  • \n - символ перевода строки;
  • \s - один из символов пробела, пробел, табуляция и так далее;
  • \S - любой символ кроме пробела;
  • \t - символ табуляции;
  • \v - символ вертикальной табуляции;
  • \w - любой буквенный символ, включая подчеркивание;
  • \W - любой буквенный символ, кроме подчеркивания;
  • \uXXX - символ Unicdoe.

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

Например, вы хотите найти в тексте строку 1+ 2=3. Если вы используете эту строку в качестве регулярного выражения, то ничего не найдете, потому что система интерпретирует плюс как спецсимвол, который сообщает, что предыдущая единица должна повториться один или больше раз. Поэтому его нужно экранировать: 1 \+ 2 = 3. Без экранирования наше регулярное выражение соответствовало бы только строке 11=3 или 111=3 и так далее. Перед равно черту ставить не нужно, потому что это не спецсимвол.

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

Теперь, когда мы рассмотрели основы и вы знаете как все работает, осталось закрепить полученные знания про регулярные выражения linux grep на практике. Два очень полезные спецсимвола - это ^ и $, которые обозначают начало и конец строки. Например, мы хотим получить всех пользователей, зарегистрированных в нашей системе, имя которых начинается на s. Тогда можно применить регулярное выражение "^s" . Вы можете использовать команду egrep:

egrep "^s" /etc/passwd

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

egrep "false$" /etc/passwd

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

egrep "^" /etc/passwd

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

egrep "^" /etc/passwd

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

egrep "^\w{3}:" /etc/passwd

Выводы

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

На завершение лекция от Яндекса про регулярные выражения:

Оригинал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публикации: 16 октября 2014 г.
Перевод: А.Панин
Дата перевода: 17 декабря 2014 г.

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

Механизм регулярных выражений являются очень мощным инструментом системы Linux. Регулярные выражения могут использоваться при работе с множеством программ, таких, как bash, vi, rename, grep, sed и других.

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

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

Существуют три различных версии синтаксисов регулярных выражений: BRE: Basic Regular Expressions (Базовый синтаксис регулярных выражений) ERE: Extended Regular Expressions (Расширенный синтаксис регулярных выражений) PCRE: Perl Regular Expressions (Синтаксис регулярных выражений языка программирования Perl)

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

К примеру, инструмент grep поддерживает параметр -E , позволяющий принудительно использовать расширенный синтаксис регулярных выражений (ERE) при разборе регулярного выражения, в то в время, как параметр -G позволяет принудительно использовать базовый синтаксис регулярных выражений (BRE), а параметр -P - синтаксис регулярных выражений языка программирования Perl (PCRE).

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

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

Всегда читайте страницы руководств используемых инструментов!

Утилита grep

Вывод строк, совпадающих с шаблоном

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

Это содержимое используемого в примерах тестового файла. Данный файл содержит три строки (или три символа новой строки). paul@rhel65:~$ cat names Tania Laura Valentina

При поиске отдельного символа будут выводиться только те строки, которые содержат заданный символ. paul@rhel65:~$ grep u names Laura paul@rhel65:~$ grep e names Valentina paul@rhel65:~$ grep i names Tania Valentina

Сравнение с шаблоном, использованным в данном примере, осуществляется очевидным образом; в том случае, если заданный символ встречается в строке, утилита grep выведет эту строку.

Объединение символов

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

В данном примере демонстрируется принцип работы утилиты grep, в соответствии с которым регулярному выражению ia будет соответствовать строка Tan ia , но не строка V a lent i na, а регулярному выражению in - строка Valent in a, но не строка Ta ni a. paul@rhel65:~$ grep a names Tania Laura Valentina paul@rhel65:~$ grep ia names Tania paul@rhel65:~$ grep in names Valentina paul@rhel65:~$

Один или другой символ

Как в синтаксисе PCRE, так и в синтаксисе ERE может использоваться символ создания программного канала, который в данном случае будет представлять логическую операцию "ИЛИ". В данном примере мы будем искать с помощью утилиты grep строки, в которых встречается символ i или символ a. paul@debian7:~$ cat list Tania Laura paul@debian7:~$ grep -E "i|a" list Tania Laura

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

Нам придется экранировать символ создания программного канала в регулярном выражении, использующем базовый синтаксис регулярных выражений (BRE) для аналогичной интерпретации этого символа в качестве логической операции "ИЛИ". paul@debian7:~$ grep -G "i|a" list paul@debian7:~$ grep -G "i\|a" list Tania Laura

Одно или большее количество совпадений

Символ * соответствует нулю, одному или большему количеству вхождений предыдущего символа, а символ + - последующего символа. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "o*" list2 ll lol lool loool paul@debian7:~$ grep -E "o+" list2 lol lool loool paul@debian7:~$

Совпадение в конце строки

В следующих примерах мы будем использовать данный файл: paul@debian7:~$ cat names Tania Laura Valentina Fleur Floor

В двух примерах ниже показана методика использования символа доллара для поиска совпадения в конце строки. paul@debian7:~$ grep a$ names Tania Laura Valentina paul@debian7:~$ grep r$ names Fleur Floor

Совпадение в начале строки

Символ вставки (^) позволяет осуществлять поиск совпадения в начале (или с первых символов) строки.

В данных примерах используется рассмотренный выше файл. paul@debian7:~$ grep ^Val names Valentina paul@debian7:~$ grep ^F names Fleur Floor

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

Разделение слов

Экранирование разыскиваемых слов с помощью символов пробелов не является удачным решением (так как другие символы также могут использоваться в качестве разделителей слов). В примере ниже показана методика использования последовательности символов \b для поиска строк с заданным словом, а не последовательностью символов: paul@debian7:~$ grep "\bover\b" text The winter is over. Can you get over there? paul@debian7:~$

Обратите внимание на то, что утилита grep также поддерживает параметр -w , предназначенный для осуществления поиска по словам. paul@debian7:~$ cat text The governer is governing. The winter is over. Can you get over there? paul@debian7:~$ grep -w over text The winter is over. Can you get over there? paul@debian7:~$

Параметры утилиты grep

Иногда оказывается проще скомбинировать простое регулярное выражение с параметрами утилиты grep , нежели создать более сложное регулярное выражение. Эти параметры обсуждались ранее: grep -i grep -v grep -w grep -A5 grep -B5 grep -C5

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

Символ доллара является специальным символом как для регулярного выражения, так и для командной оболочки (вспомните о переменных командной оболочки и встраиваемых командных оболочках). Исходя из этого, рекомендуется при любых обстоятельствах экранировать регулярные выражения, так как экранирование регулярного выражения позволяет предотвратить раскрытие этого выражения командной оболочкой. paul@debian7:~$ grep "r$" names Fleur Floor rename

Утилита rename

Реализации утилиты rename

В дистрибутиве Debain Linux по пути /usr/bin/rename расположена ссылка на сценарий /usr/bin/prename , устанавливаемый из пакета perl . paul@pi ~ $ dpkg -S $(readlink -f $(which rename)) perl: /usr/bin/prename

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

В дискуссиях об утилите rename в сети Интернет обычно происходит путаница из-за того, что решения, которые отлично работают в дистрибутиве Debian (а также Ubuntu, xubuntu, Mint, ...), не могут использоваться в дистрибутиве Red Hat (а также CentOS, Fedora, ...).

Пакет perl

Команда rename на самом деле реализована в форме сценария, использующего регулярные выражения языка программирования perl . С полным руководством по использованию данного сценария можно ознакомиться после ввода команды perldoc perlrequick (после установки пакета perldoc). root@pi:~# aptitude install perl-doc Следующие НОВЫЕ пакеты будут установлены: perl-doc 0 пакетов обновлено, 1 установлено новых, 0 пакетов отмечено для удаления, и 0 пакетов не обновлено. Необходимо получить 8,170 kB архивов. После распаковки 13.2 MB будет занято. Получить: 1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main perl-do... Получено 8,170 kБ в 19с (412 kБ/с) Выбор ранее не выбранного пакета perl-doc. (Чтение базы данных... на данный момент установлено 67121 файл и каталог.) Распаковывается perl-doc (из.../perl-doc_5.14.2-21+rpi2_all.deb) ... Adding "diversion of /usr/bin/perldoc to /usr/bin/perldoc.stub by perl-doc" Обрабатываются триггеры для man-db ... Настраивается пакет perl-doc (5.14.2-21+rpi2) ... root@pi:~# perldoc perlrequick

Хорошо известный синтаксис

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

Обычно данное действие описывается с помощью регулярного выражения s/строка/другая строка/ , как показано в примере: paul@pi ~ $ ls abc allfiles.TXT bllfiles.TXT Scratch tennis2.TXT abc.conf backup cllfiles.TXT temp.TXT tennis.TXT paul@pi ~ $ rename "s/TXT/text/" * paul@pi ~ $ ls abc allfiles.text bllfiles.text Scratch tennis2.text abc.conf backup cllfiles.text temp.text tennis.text

А ниже приведен другой пример, в котором используется хорошо известный синтаксис утилиты rename для повторного изменения расширений тех же файлов: paul@pi ~ $ ls abc allfiles.text bllfiles.text Scratch tennis2.text abc.conf backup cllfiles.text temp.text tennis.text paul@pi ~ $ rename "s/text/txt/" *.text paul@pi ~ $ ls abc allfiles.txt bllfiles.txt Scratch tennis2.txt abc.conf backup cllfiles.txt temp.txt tennis.txt paul@pi ~ $

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

В следующем примере продемонстрирована проблема, с которой можно столкнуться при использовании данного синтаксиса. paul@pi ~ $ touch atxt.txt paul@pi ~ $ rename "s/txt/problem/" atxt.txt paul@pi ~ $ ls abc allfiles.txt backup cllfiles.txt temp.txt tennis.txt abc.conf aproblem.txt bllfiles.txt Scratch tennis2.txt paul@pi ~ $

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

Глобальная замена

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

В следующем примере данный синтаксис немного расширяется благодаря добавлению модификатора. paul@pi ~ $ rename -n "s/TXT/txt/g" aTXT.TXT aTXT.TXT renamed as atxt.txt paul@pi ~ $

Теперь используемый нами синтаксис может быть описан как s/регулярное выражение/строка для замены/g , где модификатор s обозначает операцию замены (switch), а модификатор g - сообщает о необходимости осуществления глобальной замены (global).

Обратите внимание на то, что в данном примере был использован параметр -n для вывода информации о выполняемой операции (вместо выполнения самой операции, заключающейся в непосредственном переименовании файла).

Замена без учета регистра

Другим модификатором, который может оказаться полезным, является модификатор i . В примере ниже показана методика замены строки на другую строку без учета регистра. paul@debian7:~/files$ ls file1.text file2.TEXT file3.txt paul@debian7:~/files$ rename "s/.text/.txt/i" * paul@debian7:~/files$ ls file1.txt file2.txt file3.txt paul@debian7:~/files$

Изменение расширений

Интерфейс командной строки Linux не имеет представления о расширениях файлов, аналогичных применяемым в операционной системе MS-DOS, но многие пользователи и приложения с графическим интерфейсом используют их.

В данном разделе приведен пример использования утилиты rename для изменения исключительно расширений файлов. В примере используется символ доллара для указания на то, что точкой отсчета для замены является окончание имени файла. paul@pi ~ $ ls *.txt allfiles.txt bllfiles.txt cllfiles.txt really.txt.txt temp.txt tennis.txt paul@pi ~ $ rename "s/.txt$/.TXT/" *.txt paul@pi ~ $ ls *.TXT allfiles.TXT bllfiles.TXT cllfiles.TXT really.txt.TXT temp.TXT tennis.TXT paul@pi ~ $

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

Утилита sed

Редактор потока данных

Редактор потока данных (stream editor) или, для краткости, утилита sed , использует регулярные выражения для модификации потока данных.

В данном примере утилита sed используется для замены строки. echo Понедельник | sed "s/Понедель/Втор/" Вторник

Слэши могут быть заменены на некоторые другие символы, которые могут оказаться более удобными и повысить читаемость команды в ряде случаев. echo Понедельник | sed "s:Понедель:Втор:" Вторник echo Понедельник | sed "s_Понедель_Втор_" Вторник echo Понедельник | sed "s|Понедель|Втор|" Вторник

Интерактивный редактор

Несмотря на то, что утилита sed предназначена для обработки потоков данных, она также может использоваться для интерактивной обработки файлов. paul@debian7:~/files$ echo Понедельник > today paul@debian7:~/files$ cat today Понедельник paul@debian7:~/files$ sed -i "s/Понедель/Втор/" today paul@debian7:~/files$ cat today Вторник

Символ амперсанда может использоваться для ссылки на искомую (и найденную) строку.

В данном примере амперсанд используется для удвоения количества найденных строк. echo Понедельник | sed "s/Понедель/&&/" ПонедельПонедельник echo Понедельник | sed "s/ник/&&/" Понедельникник

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

Рассмотрите следующий пример: paul@debian7:~$ echo Sunday | sed "s_\(Sun\)_\1ny_" Sunnyday paul@debian7:~$ echo Sunday | sed "s_\(Sun\)_\1ny \1_" Sunny Sunday

Точка для обозначения любого символа

В регулярном выражении простой символ точки может обозначать любой символ. paul@debian7:~$ echo 2014-04-01 | sed "s/....-..-../YYYY-MM-DD/" YYYY-MM-DD paul@debian7:~$ echo abcd-ef-gh | sed "s/....-..-../YYYY-MM-DD/" YYYY-MM-DD

В случае использования более чем одной пары круглых скобок, ссылка на каждую из них может быть осуществлена путем использования последовательных числовых значений. paul@debian7:~$ echo 2014-04-01 | sed "s/\(....\)-\(..\)-\(..\)/\1+\2+\3/" 2014+04+01 paul@debian7:~$ echo 2014-04-01 | sed "s/\(....\)-\(..\)-\(..\)/\3:\2:\1/" 01:04:2014

Данная возможность называется группировкой (grouping).

Пробел

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

В данном примере осуществляется глобальный поиск последовательностей символов пробелов (\s), которые заменяются на 1 символ пробела. paul@debian7:~$ echo -e "сегодня\tтеплый\tдень" сегодня теплый день paul@debian7:~$ echo -e "сегодня\tтеплый\tдень" | sed "s_\s_ _g" сегодня теплый день

Необязательные вхождения

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

В примере ниже осуществляется поиск последовательности из трех символов o, причем третий символ o является необязательным. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "ooo?" list2 lool loool paul@debian7:~$ cat list2 | sed "s/ooo\?/A/" ll lol lAl lAl

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

Вы можете указать точное количество повторений предыдущего символа.

В данном примере осуществляется поиск строк с ровно тремя символами o. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "o{3}" list2 loool paul@debian7:~$ cat list2 | sed "s/o\{3\}/A/" ll lol lool lAl paul@debian7:~$

От n до m повторений

А в данном примере мы четко указываем, что символ должен повторяться от минимального (2) до максимального (3) количества раз. paul@debian7:~$ cat list2 ll lol lool loool paul@debian7:~$ grep -E "o{2,3}" list2 lool loool paul@debian7:~$ grep "o\{2,3\}" list2 lool loool paul@debian7:~$ cat list2 | sed "s/o\{2,3\}/A/" ll lol lAl lAl paul@debian7:~$

История командной оболочки bash

Командная оболочка bash также может интерпретировать некоторые регулярные выражения.

В данном примере показана методика манипуляций с символом восклицательного знака в рамках маски поиска в истории командной оболочки bash. paul@debian7:~$ mkdir hist paul@debian7:~$ cd hist/ paul@debian7:~/hist$ touch file1 file2 file3 paul@debian7:~/hist$ ls -l file1 -rw-r--r-- 1 paul paul 0 апр 15 22:07 file1 paul@debian7:~/hist$ !l ls -l file1 -rw-r--r-- 1 paul paul 0 апр 15 22:07 file1 paul@debian7:~/hist$ !l:s/1/3 ls -l file3 -rw-r--r-- 1 paul paul 0 Апр 15 22:07 file3 paul@debian7:~/hist$

Данная методика также работает в случае использования чисел при чтении истории команд командной оболочки bash. paul@debian7:~/hist$ history 6 2089 mkdir hist 2090 cd hist/ 2091 touch file1 file2 file3 2092 ls -l file1 2093 ls -l file3 2094 history 6 paul@debian7:~/hist$ !2092 ls -l file1 -rw-r--r-- 1 paul paul 0 апр 15 22:07 file1 paul@debian7:~/hist$ !2092:s/1/2 ls -l file2 -rw-r--r-- 1 paul paul 0 апр 15 22:07 file2 paul@debian7:~/hist$