В нашем примере мы вывели строки с 1 по 5. Для этого использовалась команда p, которая просто выводит строки, соответствующие адресам. Однако здесь нам пришлось добавить параметр -n (параметр подавления автоматического вывода), чтобы программа sed не выводила все строки, что она делает по умолчанию.
Далее попробуем задействовать регулярное выражение:
[me@linuxbox ~]$ sed -n '/SUSE/p' distros.txt
SUSE 10.2 12/07/2006
SUSE 11.0 06/19/2008
SUSE 10.3 10/04/2007
SUSE 10.1 05/11/2006
Включив регулярное выражение /SUSE/, заключенное в символы слеша, мы смогли выделить строки подобно тому, как это делает программа grep.
Наконец, попробуем применить оператор отрицания, добавив в адрес восклицательный знак (!):
[me@linuxbox ~]$ sed -n '/SUSE/!p' distros.txt
Fedora 10 11/25/2008
Ubuntu 8.04 04/24/2008
Fedora 8 11/08/2007
Ubuntu 6.10 10/26/2006
Fedora 7 05/31/2007
Ubuntu 7.10 10/18/2007
Ubuntu 7.04 04/19/2007
Fedora 6 10/24/2006
Fedora 9 05/13/2008
Ubuntu 6.06 06/01/2006
Ubuntu 8.10 10/30/2008
Fedora 5 03/20/2006
Здесь мы видим ожидаемый результат: все строки из файла, кроме совпавших с регулярным выражением.
Пока что мы познакомились лишь с двумя командами редактирования, поддерживаемыми программой sed, s и p. В табл. 20.8 приводится более полный список основных команд редактирования.
Таблица 20.8. Основные команды редактирования sed
Команда
|
Описание
|
=
|
Выводит номер текущей строки
|
a
|
Добавляет текст в конец текущей строки
|
d
|
Удаляет текущую строку
|
i
|
Вставляет текст в начало текущей строки
|
p
|
Выводит текущую строку. По умолчанию sed выводит все строки, но редактирует только соответствующие указанному адресу. Поведение по умолчанию можно отменить, передав параметр -n
|
q
|
Завершает sed без обработки остальных строк. Если параметр -n не указан, выводит текущую строку
|
Q
|
Завершает sed без обработки остальных строк
|
s/регулярное_выражение/строка_замены/
|
Замещает совпадение с регулярным выражением строкой замены. Строка замены может включать специальный символ &, обозначающий совпадение с регулярным выражением. Кроме того, строка замены может включать последовательности, с \1 по \9, обозначающие совпадения с соответствующими подвыражениями в регулярном выражении. Дополнительную информацию по этой теме можно найти в обсуждении обратных ссылок ниже. За символом слеша, закрывающим строку замены, может следовать необязательный флаг, определяющий дополнительные особенности поведения команды
|
y/множество1/множество2
|
Выполняет перекодирование, преобразуя символы из первого множества в символы второго множества. Имейте в виду, что, в отличие от программы tr, sed требует, чтобы оба множества были одинаковой длины
|
Команда s, вне всяких сомнений, используется намного чаще других команд редактирования. Далее мы рассмотрим только часть ее возможностей, выполняя редактирование нашего файла distros.txt. Мы уже говорили, что поле даты в distros.txt хранит информацию не в самом «дружественном» для компьютеров виде. Здесь даты записаны в формате ММ/ДД/ГГГГ, однако гораздо удобнее (для сортировки) было бы, если бы даты были записаны в формате ГГГГ-ММ-ДД. Замена представления дат вручную — довольно утомительное занятие и чревато ошибками, но с помощью sed ту же замену можно выполнить в одно действие:
[me@linuxbox ~]$ sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/' distros.txt
SUSE 10.2 2006-12-07
Fedora 10 2008-11-25
SUSE 11.0 2008-06-19
Ubuntu 8.04 2008-04-24
Fedora 8 2007-11-08
SUSE 10.3 2007-10-04
Ubuntu 6.10 2006-10-26
Fedora 7 2007-05-31
Ubuntu 7.10 2007-10-18
Ubuntu 7.04 2007-04-19
SUSE 10.1 2006-05-11
Fedora 6 2006-10-24
Fedora 9 2008-05-13
Ubuntu 6.06 2006-06-01
Ubuntu 8.10 2008-10-30
Fedora 5 2006-03-20
Прекрасный результат! Правда, команда выглядит устрашающе, но она работает. За один шаг мы изменили представление дат во всем файле. Этот пример также наглядно показывает, почему про регулярные выражения иногда в шутку говорят «только для записи». Мы можем писать их, но прочитать их порой никак не получается. Прежде чем сбежать от этой устрашающей команды, давайте посмотрим, как она была сконструирована. Во-первых, как мы уже знаем, эта команда имеет следующую структуру:
sed 's/регулярное_выражение/строка_замены/' distros.txt
Теперь разберем регулярное выражение, отыскивающее даты. Так как даты имеют формат ММ/ДД/ГГГГ и находятся в конце строки, найти их можно с помощью следующего выражения:
[0-9]{2}/[0-9]{2}/[0-9]{4}$
которому соответствуют две цифры, слеш, две цифры, слеш, четыре цифры и конец строки. Так, с регулярным выражением разобрались, а что со строкой замены? Чтобы описать ее, нам необходимо познакомиться с новой для нас особенностью регулярных выражений, которую можно использовать в некоторых приложениях, поддерживающих BRE. Эта особенность называется обратные ссылки, и действует она так: если в строке замены присутствует последовательность \n, где n — число от одного до девяти, эта последовательность будет ссылаться на совпадение с соответствующим подвыражением в предшествующем регулярном выражении. Чтобы создать подвыражение, достаточно просто заключить часть регулярного выражения в круглые скобки, например:
Читать дальше