sed — это двоичный файл для программы Stream EDitor, присутствующий почти во всех дистрибутивах Unix-подобных систем. Его назначение — выполнять команды выделения, редактирования и удаления над потоком текста; учитывая потоковую природу практически всего в Unix, sed может манипулировать файлами и выводом других команд, что делает его одним из воплощений философии Unix :
Это философия Unix: пишите программы, которые делают одно и делают это хорошо. Напишите программы для совместной работы. Написание программ для обработки текстовых потоков , потому что это универсальный интерфейс.
sed может передавать результаты любой команды, чтобы отфильтровать ее, или, говоря функционально, отобразить команду на нее.
команды
По умолчанию команды применяются линейно. Например, команда a добавляет строку текста после каждой совпавшей строки.
$ ls -1 /bin/ | sed -e 'aAFTER' | tail -n 4 zmore AFTER znew AFTER
Команда d удаляет строку, соответствующую определенному шаблону; в этом случае строки, начинающиеся с z.
$ ls -1 /bin/ | sed -e '/^z/d' | tail -n 4 vdir vmmouse_detect which ypdomainname
Более гибкая линейная замена — это знаменитый s :
$ ls -1 /bin/ | sed -e 's/^z//' | tail -n 4 grep less more new
который, как вы можете видеть, соответствует регулярным выражениям, а не только фиксированным строкам.
фильтрация
Также по умолчанию sed выполняет перепечатку на стандартном выводе каждой строки, которая не соответствует командам. Этот режим полезен, когда вам просто нужно отредактировать некоторые строки и оставить без изменений остальные; однако, тихий режим — лучший выбор для выполнения выбора:
$ ls -1 /bin/ | sed -n -e 'p' | tail -n 4 zgrep zless zmore znew
На этот раз мы сказали sed работать в тихом режиме с -n. Однако команда, передаваемая ей через -e, была p , что означает просто печатать каждую строку. Если бы мы убрали переключатель режима без вывода сообщений, этот вывод был бы напечатан:
$ ls -1 /bin/ | sed -e 'p' | tail -n 4 zmore zmore znew znew
который кажется излишним. sed печатает каждую строку ввода и перепечатывает ее после этого с помощью команды p.
Теперь, когда мы можем ничего не печатать по умолчанию, мы можем добавить селекторы в p, чтобы ограничить то, что мы рассматриваем во вводе. Например, мы можем выбрать только строки, соответствующие выражению в стиле grep:
$ ls -1 /bin/ | sed -n -e '/sh$/p' bash dash rbash sh static-sh
Или мы можем напечатать с 5 по 8 строку:
$ ls -1 /bin/ | sed -n -e '5,8p' bzcmp bzdiff bzegrep bzexe
Номера строк начинаются с 1, как и во всех редакторах Unix. Специальные селекторы для последней строки — $.
Мы также можем выбирать строки по шаблону вместо числа, что очень удобно для анализа многострочных журналов:
$ cat /var/log/onebip/onebip/log-*mailman-sms-connectivity* | sed -n -e '/REQUEST BODY/,/RESPONSE CODE/p' | tail -n 4 2013-10-11T15:21:01 127.0.0.1 REQUEST BODY {"country":"ES","description":"Super powers","container":"purchase\/999235"} 2013-10-11T15:21:01 127.0.0.1 RESPONSE CODE HTTP/1.1 201 Created 2013-10-11T15:21:03 127.0.0.1 REQUEST BODY {"country":"IT","description":"Super powers","container":"purchase\/1188829327"} 2013-10-11T15:21:03 127.0.0.1 RESPONSE CODE HTTP/1.1 201 Created
так как выбор может быть выполнен несколько раз, сопоставляя каждую пару REQUEST BODY и RESPONSE CODE в файле (имейте в виду, что это может не масштабироваться до более высоких пропускных способностей, если журналы могут перекрывать друг друга.)
Собираем все вместе:
$ cat /var/log/onebip/onebip/log-*mailman-sms-connectivity* | sed -n -e '/REQUEST BODY/,/RESPONSE CODE/p' | sed -e 's/.*127.0.0.1//g' | tail -n 2 REQUEST BODY {"country":"IT","description":"Super powers","container":"purchase\/1188829327","price":100,"smsc":"Mpayit"} RESPONSE CODE HTTP/1.1 201 Created
Выводы
sed находится в базовом наборе инструментов для Unix; с его помощью вы можете редактировать поток теста, подставляя выражения и фильтруя от одной до нескольких строк. Он может использоваться совместно с grep, где последний выполняет тяжелую работу по выбору, а sed редактирует по линиям.
Кроме того, его интерфейс совместим с командами Vim (команды s, p, d), и его не должно быть трудно изучить с небольшой практикой. Когда я читаю учебные пособия такого рода, я нахожу полезным вводить каждую команду, которую я хочу выучить, в моем собственном терминале, поскольку практика приводит к лучшему удержанию, чем чтение.