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

  • Проверка ввода текста;
  • Поиск и замена текста в файле;
  • Пакетное переименование файлов;
  • Взаимодействие с сервисами, таким как 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, но это были только самые основы. Если копнуть чуть глубже, вы найдете что с помощью этого инструмента можно делать намного больше интересных вещей. Время, потраченное на освоение регулярных выражений, однозначно будет стоить того.

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

Предыстория и источник: не все, кому приходится использовать регулярные выражения, до конца понимают, как они работают и как их создавать. Я тоже относился к этой группе - искал примеры регулярных выражений, подходящих под мои задачи, пытался их подправить по мере необходимости. Для меня всё в корне изменилось после прочтения книги The Linux Command Line (Second Internet Edition) автора William E. Shotts, Jr. В ней принципы работы регулярных выражений изложены настолько ясно, что после прочтения я научился их понимать, создавать регулярные выражения любой сложности и теперь использую их при каждой необходимости. Данный материал представляет собой перевод части главы, посвящённой регулярным выражениям. Этот материал предназначен для абсолютных новичков, которые совершенно не понимают, как работают регулярные выражения, но имеют некоторые представления о работе . Надеюсь, эта статья поможет вам сделать такой же прорыв, который помогла мне. Если изложенный здесь материал не содержит ничего нового для вас, попробуйте посмотреть статью «Регулярные выражения и команда grep », в ней более подробно описываются опции grep, а также имеются дополнительные примеры.

Как используются регулярные выражения

Текстовые данные играют важную роль во всех Unix-подобных системах, таких как Linux. Среди прочего, текстом является и вывод консольных программ, и файлы конфигурации, отчётов и т.д. Регулярные выражения являются (пожалуй) одной из самых сложных концепций по работе с текстом, поскольку предполагают высокий уровень абстракции. Но время, потраченное на их изучение, с лихвой окупится. Умея использовать регулярные выражения, вы сможете делать удивительные вещи, хотя их полная ценность может быть не сразу очевидной.

В этой статье будет рассмотрено использование регулярных выражений вместе с командой grep . Но их применение не ограничивается только этим: регулярные выражения поддерживаются другими командами Linux, многими языками программирования, применяются при конфигурации (например, в настройках правил mod_rewrite в Apache), а также некоторые программы с графическим интерфейсом позволяют устанавливать правила для поиска/копирования/удаления с поддержкой регулярных выражений. Даже в популярной офисной программе Microsoft Word для поиска и замены текста вы можете использовать регулярные выражения и подстановочные символы.

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

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

grep

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

grep может делать поиск по тексту, получаемому в стандартном вводе, например:

Ls /usr/bin | grep zip

Эта команда выведет список файлов в директории /usr/bin, чьи имена содержат подстроку «zip».

Программа grep может искать по тексту в файлах.

Общий синтаксис использования:

Grep [опции] regex [файл...]

  • regex - это регулярное выражение.
  • [файл…] - один или несколько файлов, в которых будет проводиться поиск по регулярному выражению.

[опции] и [файл…] могут отсутствовать.

Список самых часто используемых опций grep:

Опция Описание
-i Игнорировать регистр. Не делать различия между большими и маленькими символами. Также можно задать опцией --ignore-case .
-v Инвертировать соответствие. Обычно grep печатает строки, которые содержат соответствие. Эта опция приводит к тому, что grep выводит каждую строку, которая не содержит соответствия. Также можно использовать --invert-match .
-c Печатать количество соответствий (или несоответствий, если указана опция -v ) вместо самих строк. Можно также указывать опцией --count .
-l Вместо самих строк печатать имя каждого файла, который содержит соответствие. Можно указать опцией --files-with-matches .
-L Как опция -l , но печатает только имена файлов, которые не содержат совпадений. Другое имя опции --files-withoutmatch .
-n Добавление к началу каждой совпавшей строке номера строчки внутри файла. Другое имя опции --line-number .
-h Для поиска по нескольким файлам, подавлять вывод имени файла. Также можно указать опцией --no-filename .

Чтобы полнее исследовать grep, давайте создадим несколько текстовых файлов для поиска:

Ls /bin > dirlist-bin.txt ls /usr/bin > dirlist-usr-bin.txt ls /sbin > dirlist-sbin.txt ls /usr/sbin > dirlist-usr-sbin.txt ls dirlist*.txt dirlist-bin.txt dirlist-sbin.txt dirlist-usr-bin.txt dirlist-usr-sbin.txt

Мы можем выполнить простой поиск по нашему списку файлов следующим образом:

Grep bzip dirlist*.txt dirlist-bin.txt:bzip2 dirlist-bin.txt:bzip2recover

В этом примере grep ищет по всем перечисленным файлам строку bzip и находит два соответствия, оба в файле dirlist-bin.txt. Если нас интересует только список файлов, содержащих соответствия, а не сами подходящие строки, мы можем указать опцию -l :

Grep -l bzip dirlist*.txt dirlist-bin.txt

И наоборот, если бы мы хотели увидеть только список файлов, которые не содержали совпадений, мы могли бы сделать это:

Grep -L bzip dirlist*.txt dirlist-sbin.txt dirlist-usr-bin.txt dirlist-usr-sbin.txt

Если вывод отсутствует - значит файлы, удовлетворяющие условиям не найдены.

Метасимволы и литералы

Хотя это может показаться неочевидным, наши поиски с grep всегда используют регулярные выражения, хоть и очень простые. Регулярное выражение «bzip» означает, что совпадение будет происходить (т.е. строка будет считаться подходящей) только в том случае, если строка в файле содержит не менее четырех символов и что где-то в строке символы «b», «z», «i» и «p» находятся в этом порядке, без других символов между ними. Символы в строке «bzip» являются литералами , т.е. буквальными символами , поскольку они соответствуют самим себе. В дополнение к литералам регулярные выражения могут также включать метасимволы , которые используются для задания более сложных совпадений. Метасимволы регулярного выражения состоят из следующих:

^ $ . { } - ? * + () | \

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

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

Любой символ

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

Grep -h ".zip" dirlist*.txt bunzip2 bzip2 bzip2recover gunzip gzip funzip gpg-zip mzip p7zip preunzip prezip prezip-bin unzip unzipsfx

Мы искали любую строку в наших файлах, которая соответствует регулярному выражению «.zip». Нужно отметить парочку интересных моментов в полученных результатах. Обратите внимание, что программа zip не была найдена. Это от того, что включение метасимвола точка в наше регулярное выражение увеличило длину, требуемую для совпадения, до четырёх символов, а поскольку имя «zip» содержит только три, то оно не соответствует. Также если какие-либо файлы из наших списков содержали расширение файла.zip, они также считались бы подходящими, поскольку символ точки в расширении файла, также подходит под условие «любой символ».

Анкоры

Символ каретки (^ ) и знак доллара ($ ) считаются в регулярных выражениях анкорами . Это означает, что они вызывают совпадение, только если регулярное выражение найдено в начале строки (^ ) или в конце строки ($ ):

Grep -h "^zip" dirlist*.txt zip zipcloak zipdetails zipgrep zipinfo zipnote zipsplit grep -h "zip$" dirlist*.txt gunzip gzip funzip gpg-zip mzip p7zip preunzip prezip unzip zip grep -h "^zip$" dirlist*.txt zip

Здесь мы искали по спискам файлов строку «zip», расположенную в начале строки, в конце строки, а также в строке, где она была бы одновременно и в начале, и в конце (т.е. вся строка содержала бы только «zip»). Обратите внимание, что регулярное выражение «^$ » (начало и конец между которыми ничего нет) будет соответствовать пустым строкам.

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

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

Если вы когда-нибудь разгадывали кроссворды, то вам нужно было решать задачи вроде «что за слово из пяти букв, где третья буква «j», а последняя буква «r», которое означает…». Этот вопрос может заставить задуматься. Знаете ли вы, что в системе Linux есть словарь? А он есть. Загляните в директорию /usr/share/dict, там вы можете найти один или несколько словарей. Словари, размещённые там, это просто длинные списки слов по одному на строку, расположенные в алфавитном порядке. В моей системе файл словаря содержит 99171 слов. Для поиска возможных ответов на вышеприведённый вопрос кроссворда, мы можем сделать так:

Grep -i "^..j.r$" /usr/share/dict/american-english Major major

Используя это регулярное выражение, мы можем найти все слова в нашем файле словаря, которое имеет длину в пять букв, имеет «j» в третьей позиции и «r» в последней позиции.

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

Выражения в квадратных скобках и Классы символов

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

Grep -h "zip" dirlist*.txt bzip2 bzip2recover gzip

мы найдём любые строчки, содержащие строки «bzip» или «gzip».

Набор может содержать любое количество символов, а метасимволы теряют своё специальное значение, когда помещаются внутрь квадратных скобок. Тем не менее, есть два случая в которых метасимволы, используемые внутри квадратных скобок, имеют различные значения. Первый - это каретка (^ ), которая используется для указания отрицания; второй - это тире (- ), которое используется для указания диапазона символов.

Отрицание

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

Grep -h "[^bg]zip" dirlist*.txt bunzip2 gunzip funzip gpg-zip mzip p7zip preunzip prezip prezip-bin unzip unzipsfx

С активированным отрицанием, мы получили список файлов, которые содержат строку «zip», перед которой идёт любой символ, кроме «b» или «g». Обратите внимание, что zip не был найден. Отрицаемый набор символов всё равно требует символ на заданной позиции, но символ не должен быть членом инвертированного набора.

Символ каретки вызывает отрицание только если он является первым символом внутри выражения в квадратных скобках; в противном случае, он теряет своё специальное назначение и становится обычным символом из набора.

Традиционные диапазоны символов

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

Grep -h "^" dirlist*.txt MAKEDEV GET HEAD POST VBoxClient X X11 Xorg ModemManager NetworkManager VBoxControl VBoxService

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

Grep -h "^" dirlist*.txt

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

Grep -h "^" dirlist*.txt

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

Grep -h "" dirlist*.txt

Это будет соответствовать каждому имени файла, содержащему заглавную букву. При этом:

Grep -h "[-AZ]" dirlist*.txt

будет соответствовать каждому имени файла, содержащему тире, или заглавную «A», или заглавную «Z».

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

Регулярные выражения Bash разработаны Брайаном Фоксом для проекта GNU как альтернативная смена ПО для оболочки Bourne. Командный язык был издан в 1989 году и массово распространился в качестве оболочки входа по умолчанию для дистрибутивов Linux и MacOS через Apple (прежде OS X). Версия тоже доступна для Windows 10 и является оболочкой пользователя по умолчанию в Solaris 11.

Bash - это инструктивный процессор, традиционно работающий в текстовом терминале, где разработчик запускает команды, вызывающие действия. Регулярные выражения Bash читаются и исполняются из файла, именуемого сценарием оболочки. Вместе с Unix он распознает имена файлов (сравнение подстановочных символов), протоколы, документы, подстановку директив и структуры управления для тестирования критериев. В главных словах синтаксис и другие ключевые индивидуальности языка воспроизводятся из csh и ksh. Bash - это POSIX- совместимая оболочка, но с некоторыми расширениями. Название оболочки - это сокращение от

Брайан Фокс начал кодировать "Баша" 10 января 1988 года после того, как Ричард Столлман был недоволен отсутствием прогресса в разработках бесплатной оболочки, которая могла бы запускать существующие сценарии. Фокс выпустил Bash как бета-версию 8 июня 1989 года и оставался основным разработчиком проекта с середины 1992 года и до середины 1994 года, после чего он был уволен из ФСФ, а его место занял Чет Рами.

В этот период Bash была самой популярной программой среди пользователей Linux, став интерактивной оболочкой по умолчанию в различных дистрибутивах этой операционной системы, а также в MacOS от Apple. Bash также была вкраплена в Microsoft Win с Cygwin, в DOS по DJGPP проекту и Android с помощью различных приложений эмуляции терминала.

В начале сентября 2014 года была обнаружена приличная брешь безопасности в "Баше" версии 1.03, вышедшей в августе 1989 года, получившая название Shellshock, которая привела к целому ряду атак через Интернет. Ошибка считалась серьезной, поскольку с использованием Bash стали уязвимыми, что позволило выполнять произвольный код. Патчи для исправления ошибок стали доступными сразу же после их обнаружения, но не все компьютеры были обновлены.

Особенности синтаксиса оболочки

Bash является надмножеством команд оболочки Bourne и использует расширение брекетов, завершение командной строки, базовую отладку и обработку исключений с применением ловушки среди других функций. Выполняет подавляющее большинство сценариев оболочки Bourne без изменений, за исключением сценариев, которые по-разному интерпретируются или пытаются запустить системную команду. Регулярные выражения Bash grep, а также инструменты GNU используют сжатый способ сканирования ошибок ПО и устанавливают статус выхода, что позволяет потокам переходить к традиционным пунктам назначения.

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

Регулярные выражения Bash: исполнение цельночисленных расчетов арифметической оценки, употребляется ((...)) команда и $ ((...)) аргумент синтаксиса, упрощающий переадресовывание ввода-вывода. Например, он имеет возможность перенаправлять вывод (stdout) и сбой (stderr) синхронно с поддержкой &>оператора. Настоящее легче ввести, нежели эквивалент оболочки Bourne " command > file 2>&1".

Bash использует замещение процесса с поддержкой синтаксиса регулярных выражений "Линукс" и подменяет вывод команды (ввода), традиционно применяющий имя файла. При использовании ключевого слова «функция», объявления Bash несовместимы со сценариями Bourne и Korn, так как оболочка Korn имеет ту же проблему при применении «функции», но она принимает тот же синтаксис объявления функции, что и вышеназванные оболочки, являясь POSIX-совместимой.

Из-за этих и других отличий сценарии редко выполняются под интерпретаторами Bourne и Korn, если они не были специально написаны с учетом этой совместимости, что нужно учитывать при планировании работы с регулярными выражениями Bash. Ассоциативные массивы позволяют поддельную поддержку индексированных массивов, аналогично AWK. Bash 4.x не был интегрирован в новую версию MacOS из-за ограничений лицензии. Пример ассоциативного массива.

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

  • command1;
  • command2.

В этом примере, когда команда 1 завершена, выполняется команда 2. И так же можно выполнить фоновое выполнение команды 1 с помощью (symbol &) в конце выполнения, процесс будет выполняться в фоновом режиме, возвращая сразу управление оболочке и позволяя пользователю применять исполняемые команды.

Для одновременного выполнения команд 1 и 2 они должны быть выполнены в оболочке следующим образом:

  • command1 & command2.

В этом случае команда 1 выполняется в фоновом режиме & symbol, возвращая сразу управление оболочке, которая выполняет команду 2 на переднем плане. Регулярные выражения Bash grep можно остановить и вернуть управление, набрав Ctrl + z, пока процесс выполняется на переднем плане. Список всех процессов, как в фоновом режиме, так и в режиме остановки, может быть, достигнут путем запуска jobs.

Состояние процесса можно изменить с помощью различных команд. Команда "fg" выводит процесс на передний план, а "bg"-набор останавливает процесс, выполняющийся в фоновом режиме. Bg" и "fg" могут принять идентификатор работы в качестве своего первого аргумента, чтобы указать, в каком процессе действовать. Без этого они используют процесс по умолчанию, обозначенный знаком «плюс» в выводе "jobs". Команда "kill" может использоваться для завершения процесса преждевременно, отправив ему сигнал. Идентификатор задания должен быть указан после знака процента:

  • kill -s SIGKILL% 1 или kill -9%.

Bash поставляет «условное исполнение» разделителям команд, которые выполняют команды "contingent" по коду выхода, установленного командой прецедента. Внешняя команда, называемая "bashbug", сообщает об ошибках оболочки. Когда команда вызывается, она запускает редактор по умолчанию для пользователя с заполненной формой. Форма отправляется сторонам Bash или, возможно, другим адресам электронной почты, обеспечив глобально замену регулярных выражений Bash.

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

  • #!/bin/bash.

Файлы инициализации, применяемые Bash выражения с присвоением не требуют этого. Порядок исполнения файлов:

  1. При запуске оболочки он читает и исполняет /etc/profile, в случае если он имеется.
  2. Данный файл инициирует /etc/bash.bashrc.
  3. После определения данного файла он отыскивает ~/.bash_profile, считывая и исполняя 1-й, существующий и читаемый.
  4. Если оболочка следует из , он определяет и исполняет ~/.bash_logout.
  5. Во время запуска в роли оболочки он определяет и исполняет /etc/bash.bashrc, а потом ~/.bashrc.
  6. Настоящее имеет возможность запрещения через "--norc" опцию.
  7. Параметр "--rcfile" file вынуждает Bash прочитывать и исполнять его.
  8. Сопоставление с Bourne shell и csh startup , выходят из оболочки "Борна" и csh. Они разрешают сузить общее использование файлов с Bourne и позволить отдельные функции пуска, известные юзерам csh.

Вызов Bash с -posix опцией или указание set -o posix в скрипте заставляет регулярное выражение для экранирования Bash очень точно соответствовать стандарту POSIX 1003.2. Сценарии оболочки, предназначенные для переносимости, должны по крайней мере учитывать оболочку Bourne, которую она намеревается заменить. У Bash есть определенные функции, которых не хватает традиционной оболочке Bourne. К ним относятся:

  1. Некоторые расширенные варианты вызова.
  2. Подстановка команд с использованием нотации $ (). Эта функция является частью стандарта POSIX 1003.2.
  3. Расширение скобок.
  4. Некоторые операции с массивами и ассоциативные массивы.
  5. Расширение тестовой конструкции с двойными скобками.
  6. Арифметико-оценочная конструкция регулярных выражений Bash в "if".
  7. Некоторые операции манипуляции строкой.
  8. Замена процесса.
  9. Оператор соответствия регулярному выражению.
  10. "Баш"-специфические встроенные Coprocesses.

Арифметические выражения Bash используют "readline" для предоставления быстрых клавиш и редактирования командной строки с использованием привязок клавиш по умолчанию (Emacs). Vi-привязки могут быть включены при запуске "set -o vi".

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

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

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

  • $ start = 1 ;
  • end = 10 $ echo { $ start .. $ end } # не может расширяться из-за порядка оценки {1..10};
  • $ eval echo { $ start .. $ end } # расширение переменной происходит, тогда результирующая строка оценивается: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.

Синтаксические аспекты языка "Баша"

Сценарии оболочки должны храниться в текстовом файле ASCII, созданном с использованием программы «editor», которая не вводит дополнительные символы или последовательности для форматирования текста. Например, редакторы, подходящие для создания сценариев оболочки, - это программы vi или Emacs, доступные в UNIX / Linux, или такие программы, как «Блокнот», TextEdit и UltraEdit в Microsoft Windows.

Хорошей практикой является вставка в первую строку каждого сценария Bash регулярки, последовательности «#! / Bin / bash», которая показывает абсолютный путь программы в файловой системе машины, на которой нужно запустить скрипт. Таким образом, можно запустить его непосредственно в командной строке, не указывая имя файла в качестве аргумента команды «bash».

Указание программы-переводчика, которая будет использоваться операционной системой для перевода и выполнения инструкций скрипта, предоставляется в первой строке самого скрипта, сразу после последовательности символов «#!». Считается, что исполняемый файл интерпретатора находится в каталоге « / bin», но в разных системах он может быть установлен в других каталогах, например:

  • « / usr / bin », « / usr / local / bin ».

В общем случае символ «#» позволяет вводить комментарий в источнике сценария. Любой символ в строке сценария после символа «#» игнорируется командным интерпретатором. Фактически он часто используется для вставки комментариев в источник сценария для описания его работы или для объяснения влияния конкретных команд. Как и при вставке команд в интерактивном режиме, даже при кодировании скрипта, каждая инструкция программы может быть записана на отдельной строке или разбита на несколько строк и заканчивает каждую строку, кроме последней, символом « \ ». Дополнительные инструкции можно сообщать в той же строке, используя «;».

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

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

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

Сценарий запускается автоматически операционной системой, когда пользователь входит в саму систему, то есть может быть выполнен пользователем посредством команды, заданной на уже открытой оболочке, или с помощью специальных графических утилит, если он работает с системой с графическим интерфейсом пользователя. Например, на компьютере Apple Macintosh под управлением Mac OS X можно использовать командную оболочку, запустив утилиту Terminal, расположенную в Utility в папке «Приложение».

На рабочей станции Linux с графическим менеджером рабочего стола, например GNOME или KDE, можно открыть командную оболочку, выбрав программу «Терминал» из меню «Приложения → Аксессуары». После активации командной оболочки можно просмотреть имя используемой нами оболочки, выполнив следующие команды:

  • $ echo;
  • $SHELL /bin/bash.

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

  • $ echo $SHELL /bin/tcsh $ which bash /bin/bash $ bash bash-2.03$.

Оболочка, таким образом, работает в интерактивном режиме, получая входные данные в каждую отдельную команду и параметры, указанные в командной строке, и выполняя саму команду. Вывод отображается в том же окне терминала. Каждая команда, передаваемая оболочке, заканчивается нажатием клавиши Invio/Enter. Можно выпустить несколько команд в одной строке, отделяя их друг от друга символом «;». Также возможно разбить вставку команды на две или более строк, заканчивая каждую промежуточную строку символом « \ ».

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

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

Для разграничения строк используются двойные кавычки, однако если строка ограничена этим символом, интерпретатор выполняет так называемую «интерполяцию» и разрешает значение любых переменных в регулярных выражениях Bash в строке. На практике если в строке, заключенной в двойные кавычки, есть ссылка на переменную, то в строке имя переменной заменяется ее значением. Чтобы напечатать символы, например двойные кавычки или доллар, которые иначе интерпретировались бы и принимали бы другое значение, необходимо прописывать префикс каждого из них символом « \ » обратной косой черты. Чтобы напечатать символ обратной косой черты в строке, ограниченной двойными кавычками, нужно вернуть две обратные косые черты.

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

Если нужно выполнить оболочку таким образом, чтобы она обрабатывала последовательность команд, показанных в текстовом файле ASCII:

  • $ pwd ;
  • echo $SHELL ;
  • hostaname /home/marco /bin/bash aquilante $ echo \ > $SHELL /bin/bash.

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

  • echo -n "Oggi e" il " 2 date +%d/%m/%Y.

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

  • $ bash script.sh Oggi e" il 10/6/2011.

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

  • $ cat script.sh | bash Oggi e" il 10/6/2011.

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

  • $ cat script.sh #!/bin/bash echo -n "Oggi e" il " date +%d/%m/%Y $ chmod 755 script.sh $ ls -l script.sh -rwxr-xr-x 1 marco users 49 18 Apr 23:58 script.sh $ ./script.sh Oggi e" il 10/6/2011.

В последней команде предыдущего примера, непосредственно вызывающей выполнение скрипта, хранящегося в файле «script.sh», присутствующем в текущем каталоге, указан относительный путь « ./ » до имени файла. Необходимо указать путь к каталогу, в котором находится исполняемый скрипт, потому что часто по соображениям безопасности текущий каталог отсутствует в списке каталогов, в которых оболочка должна искать внешние исполняемые команды. Список таких каталогов хранится в переменных регулярных выражениях Bash.

Преимущества операционной системы с Bash

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

Если сравнить скрипты с изучением конфигурации или системы автоматизации "yaml" или "json", они намного более универсальны. Сценарии Bash более просты, потому что скрипт работает по умолчанию.

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

С помощью Bash разработчики могут использовать интерактивный веб-опыт, применяя опыт командной строки Linux без границ времени и места. Для использования этой возможности не требуются строгие правила и усилия, и пользователи могут получить доступ к аутентифицированной рабочей станции, управляя ресурсами и средой Azure одним кликом, даже когда они используют мобильные приложения Azure, Azure Portal и Azure Documentation.

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

Мы рассмотрели примеры регулярных выражений Bash. Удачи в освоении!

Оригинал: 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$

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

  • Проверка ввода текста;
  • Поиск и замена текста в файле;
  • Пакетное переименование файлов;
  • Взаимодействие с сервисами, таким как 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, но это были только самые основы. Если копнуть чуть глубже, вы найдете что с помощью этого инструмента можно делать намного больше интересных вещей. Время, потраченное на освоение регулярных выражений, однозначно будет стоить того.

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