Regex регулярные выражения bash. Регулярные выражения и команда grep

29.11.2023 Windows 7

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

Регулярные выражения 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. Удачи в освоении!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Жадность regex

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.*^${}+?|()

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

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

There is 10$ on my pocket

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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


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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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


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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

[email protected]

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

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

^(+)@

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

(+)

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

.({2,5})$

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

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

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

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

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


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

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

Итоги

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

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

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

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

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

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

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

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

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

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





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

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

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

Общие опции

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

...
...

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

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

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

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

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

grep "(*)" GPL-3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Чередование

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

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

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

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

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

Кванторы

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

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

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

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

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

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

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

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

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

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

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

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

Выводы

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

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

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

Tags: ,