[me@linuxbox ~]$ echo "aaabbbccc" | tr -s ab
abccc
Здесь у нас имеется строка с повторяющимися символами. Передав множество ab команде tr, мы удалили повторяющиеся экземпляры символов, входящие в множество, при этом остальные символы (c), отсутствующие в множестве, остались нетронутыми. Обратите внимание, что повторяющиеся символы должны следовать подряд. В противном случае сжатие не даст никакого эффекта:
[me@linuxbox ~]$ echo "abcabcabc" | tr -s ab
abcabcabc
sed — потоковый редактор для фильтрации и преобразования текста
Имя sed — это сокращенное словосочетание stream editor (потоковый редактор). Данная команда осуществляет редактирование потока текста, получаемого из множества файлов или подаваемого на стандартный ввод команды. sed — мощная и достаточно сложная программа (ей посвящены целые книги), поэтому здесь мы не будем рассматривать ее во всех подробностях.
В общем случае sed используется следующим образом: ей передается единственная команда редактирования (в командной строке) или имя файла сценария с множеством команд, и она применяет эти команды к каждой строке в потоке текста. Ниже приводится очень простой пример sed в действии:
[me@linuxbox ~]$ echo "front" | sed 's/front/back/'
back
В этом примере с помощью echo создается поток текста с единственным словом, который по конвейеру передается программе sed. sed, в свою очередь, применяет инструкцию s/front/back/ к тексту в потоке и выводит результат. Эта команда напоминает команду подстановки (поиск с заменой) в редакторе vi.
Команды sed начинаются с единственной буквы. В примере, рассмотренном выше, буква s представляет команду подстановки (substitution). За ней следуют искомая строка и строка замены, разделенные слешем. В качестве разделителя можно использовать любые символы. По общепринятому соглашению, чаще других используется символ слеша, но sed будет использовать в качестве разделителя любой символ, следующий сразу за командой. Ту же самую команду можно было бы записать иначе:
[me@linuxbox ~]$ echo "front" | sed 's_front_back_'
back
Символ подчеркивания, следующий сразу за командой, становится разделителем. Возможность употребления произвольных разделителей можно использовать для улучшения читаемости команд, как будет показано далее.
Большинству команд в sed может предшествовать адрес, который определяет, какие строки во входном потоке должны редактироваться. Если адрес отсутствует, команда редактирования применяется ко всем строкам во входном потоке. В простейшем случае адрес — это номер строки. Мы могли бы добавить единицу в наш пример:
[me@linuxbox ~]$ echo "front" | sed '1s/front/back/'
back
Добавление адреса 1 в команду гарантирует применение операции подстановки только к первой строке в нашем однострочном потоке. Можно указать другое число:
[me@linuxbox ~]$ echo "front" | sed '2s/front/back/'
front
Теперь, как видите, редактирование не было выполнено, потому что во входном потоке отсутствует строка с номером 2.
Адреса можно выражать множеством способов. В табл. 20.7 перечислены адреса, чаще других используемые на практике.
Таблица 20.7. Форма записи адресов в команде sed
Адрес
|
Описание
|
n
|
Номер строки, где n — положительное число
|
$
|
Последняя строка
|
/регулярное_выражение/
|
Строки, соответствующие простому регулярному выражению POSIX. Обратите внимание, что регулярное выражение должно ограничиваться символом слеша с обеих сторон. При желании можно использовать другие ограничительные символы, определив регулярное выражение в форме \cрегулярное_выражениеc, где c — альтернативный символ-ограничитель
|
адр1,адр2
|
Диапазон строк с номерами от адр1 по адр2 включительно. Каждый адрес может иметь любую форму из перечисленных выше
|
первая~шаг
|
Соответствует строке с номером первая и каждой последующей с указанным шагом. Например, адрес 1~2 соответствует всем строкам с нечетными номерами, а адрес 5~5 соответствует пятой строке и каждой пятой последующей
|
адр1,+n
|
Соответствует строке с адресом адр1 и следующим за ней n строкам
|
adr!
|
Соответствует всем строкам, кроме строки с адресом адр, где адрес может иметь любую форму из перечисленных выше
|
Рассмотрим разные способы адресации строк на примере файла distros.txt, созданного выше в этой главе. Сначала попробуем диапазоны номеров строк:
[me@linuxbox ~]$ sed -n '1,5p' distros.txt
SUSE 10.2 12/07/2006
Fedora 10 11/25/2008
SUSE 11.0 06/19/2008
Ubuntu 8.04 04/24/2008
Fedora 8 11/08/2007
Читать дальше