Замена символов в строке. Команда s/ / /
Слушай как сквозь кожу прорастает рожь
Слушай как по горлу пробегает мышь
Слушай как в желудке пузырится смех
Слушай как бежит по вздутым венам вдаль твоя сладкая радуга
Звонкая радуга
Как на яблоне на ветке созревает звезда
Крошечная, поздняя, милая, ручная
Слушай как блуждают по покинутым селеньям
Шальные хороводы деревянных невест.
Слушай как под сердцем колосится рожь.
Слушай как по горлу пробегает мышь
Слушай как в желудке распухает ночь
Как вонзается в ладонь стебелёк
Как лениво высыхает молоко на губах
Как ворочается в печени червивый клубок
Как шевелятся кузнечики в пустом янтаре
Погружаясь в изнурительное бегство в никуда из ниоткуда
Вот и хорошо вот и баиньки
Страшно безымянному заиньке
Под глазастыми заборами в удушливых потёмках
Своего замысловатого, сырого нутра.
Вот с этого места я и начну описание регулярных выражений вообще и команды sed в частности. И начну я с основной команды sed - замены символов в строке. Синтаксис прост:
s/ЧТО_ИЩЕМ/НА_ЧТО_МЕНЯЕМ/разные_модификаторы
к примеру(здесь и далее пример с начала топика, ©Гражданская Оборона)
ну вот к примеру:
Слуш>а<й как сквозь кожу прорастает рожь
Слуш>а<й как по горлу пробегает мышь
Слуш>а<й как в желудке пузырится смех
Слуш>а<й как бежит по вздутым венам вдаль твоя сладкая радуга
Звонк>а<я радуга
К>а<к на яблоне на ветке созревает звезда
Крошечн>а<я, поздняя, милая, ручная
Слуш>а<й как блуждают по покинутым селеньям
Ш>а<льные хороводы деревянных невест.
Слуш>а<й как под сердцем колосится рожь.
Слуш>а<й как по горлу пробегает мышь
Слуш>а<й как в желудке распухает ночь
К>а<к вонзается в ладонь стебелёк
К>а<к лениво высыхает молоко на губах
К>а<к ворочается в печени червивый клубок
К>а<к шевелятся кузнечики в пустом янтаре
Погруж>а<ясь в изнурительное бегство в никуда из ниоткуда
Вот и хорошо вот и б>а<иньки
Стр>а<шно безымянному заиньке
Под гл>а<застыми заборами в удушливых потёмках
Своего з>а<мысловатого, сырого нутра.
Принцип работы sed в данном случае очень прост: как всегда sed обрабатывает весь текст по одной строке, так-как мы не указали какие строки надо обрабатывать, то обрабатываются все. В текущей строке ищется буква "а", и как только она находится, она заменяется на ">а<". После чего sed начинает обрабатывать следующую строку. Уже с первой строчки видно, что sed меняет
только первое
совпадение. Это можно поменять, если добавить в конце команды модификатор g, тогда обрабатываться будет все совпадения. Впрочем это не столь важно. Намного важнее, что искать и менять можно не только одну конкретную букву, но и
любое регулярное выражение
. К примеру, я тут расстраивался, что sed не умеет раскрашивать совпадения, в отличие от той-же grep. Что-ж, посмотрим... Если в строке есть какое-то слово, тогда это слово делит строку на 3 части:
-
от начала строки до слова.
Тут нам понадобится якорь, а именно начало строки. Регулярные выражения в shell(bash), на примере использования sed. - Якоря и границы
ну и после начала могут находится любые символы в любом количестве(а могут и не находится). эту часть строки мы будем распечатывать обычным цветом. -
найденное слово.
это слово надо выделить цветом. Делается это очень просто: Команды (esc-последовательности) syscons
просто нужно вставить специальную последовательность, и терминал будет выводить символы в нужном цвете(это кстати важное преимущество sed, другие команды обычно глючат при работе с непечатными символами, sed нормально обрабатывает что угодно, хоть русский шрифт в любой кодировке, хоть ESC последовательности.) Будем выделять красным. Код для этого - \x1b[31m. А после найденного слова нужно вернуть цвет на нормальный: \x1b[0m. - Ну а после слова нужно вывести оставшийся кусок строки. Как не странно, якоря нам тут не понадобятся, достаточно просто указать "что угодно в любом количестве". Дело в том, что sed жадная, и если у неё есть вывод сколько пожрать символов, то она пожрёт столько, сколько сможет. Подробнее о жадности ниже.
Начнём создавать команду: Во первых нам нужно печатать не все строки, а только стрки в которых содержится нужное слово(в общем случае не только слово, но и любое допустимое условие). Для определённости возьмём слово "на". Лично я сразу набираю и опробую выражения, и смотрю что получается. ИМХО ERE это не то, что делается с карандашом и бумагой, тут комп нужен
Как на яблоне на ветке созревает звезда
Крошечная, поздняя, милая, ручная
Как лениво высыхает молоко на губах
Ну вот - пол дела сделано, строки найдены, осталось выделить цветом то, что мы нашли.
Как наяблоне на ветке созревает звезда
Крошечна, поздняя, милая, ручная
Как лениво высыхает молоко нагубах
Вот. Даже работает... Только теперь всё вообще красное, даже приглашение. (если вы что-нить накрутили, и вам (почти)ничего не видно - наберите в консоли в слепую
reset
, это вернёт цвета и т.д. на начальные значения). Перед тем, как разбиратся в чём ошибка, я бы хотел обратить ваше внимание на символ
&
в команде - этот спец символ означает "заменить на совпадение", точнее на то, что мы нашли. Ищем мы "на".
Сразу скажу, что ищем мы 2 раза: первый раз в условии(надо ли это строку обрабатывать), а второй раз в самой команде замены
s
. Это довольно не экономично, и для этого случая у команды s предусмотрен особый синтаксис - можно в этом случае просто не писать выражение для поиска(так-как образец уже найден). sed -rn '/на/ s//.../p'
А ошибка простая - при отключении цвета я забыл написать букву m
Вот исправленный вариант:
Как на яблоне на ветке созревает звезда
Крошечная, поздняя, милая, ручная
Как лениво высыхает молоко на губах