Библиотека сайта rus-linux.net
Фундаментальные основы Linux. Часть IV. Программные каналы и команды
Оригинал: 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
выведет эту строку.
Объединение символов
Для поиска сочетаний символов в строках символы регулярного выражения должны объединяться аналогичным образом.
ia
будет соответствовать строка Tania
, но не строка Va
lenti
na, а регулярному выражению in
- строка Valentin
a, но не строка Tani
a.
paul@rhel65:~$ grep a names Tania Laura Valentina paul@rhel65:~$ grep ia names Tania paul@rhel65:~$ grep in names Valentina paul@rhel65:~$
Один или другой символ
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:~$ cat text The governer is governing. The winter is over. Can you get over there?
over
будет выведено слишком много результирующих строк.
paul@debian7:~$ grep over text The governer is governing. The winter is over. Can you get over there?
\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
/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
может использоваться для ссылки на такой символ, как символ пробела или табуляции.
paul@debian7:~$ echo -e 'сегодня\tтеплый\tдень' сегодня теплый день paul@debian7:~$ echo -e 'сегодня\tтеплый\tдень' | sed 's_\s_ _g' сегодня теплый день
Необязательные вхождения
Символ знака вопроса указывает на то, что предыдущий символ является необязательным
.
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 повторений
Вы можете указать точное количество повторений предыдущего символа.
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 повторений
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
также может интерпретировать некоторые регулярные выражения.
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$
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$
Предыдущий раздел: | Оглавление | Следующий раздел: |
Глава 18. Стандартные инструменты систем Unix | Глава 20. Начальные сведения о текстовом редакторе vi |