Библиотека сайта 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, но не строка Valentina, а регулярному выражению in - строка Valentina, но не строка Tania.
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 |
