Потоковый редактор sed
Редактор sed получает входной поток построчно, редактирует каждую строку согласно правилам, и затем выводит результат в выходной поток. Набор команд sed сделан по образцу строкового редактора ed.
Следующий пример демонстрирует типичное использование sed:
$ sed 's/шаблон/замена/g' inputFile > outputFile
Редактор ищет в файле inputFile
строки, содержащие шаблон
и заменяет в них найденные совпадения на замена
. Вывод перенаправляется в файл outputFile
. Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. По умолчанию, заменяется только первое вхождение шаблона
в каждой строке. Модификатор g
предписывает заменить все вхождения.
Как это работает
1. Загрузка строки из потока
На этом этапе строка загружается в буфер. Буфером называется выделенная sed область памяти, размер которой не ограничен (на практике размер ограничен объёмом оперативной и swap-памяти). Загрузка заканчивается после чтения из потока символа новой строки или после завершения потока. При этом символ новой строки хотя и читается из потока, однако не пишется в буфер.
2. Обработка строки в буфере
На этом этапе выполняется sed-скрипт, при этом содержимое буфера обычно изменяется. Скрипт состоит из особых команд, каждая из которых представляет собой одну из букв латинского алфавита. Малые и большие буквы различаются — n
и N
это разные команды. Проще всего записывать команды в командной строке, сразу после sed и её опций.
$ sed -n 'p;p;p'
Команды могут изменить содержимое буфера, но кроме того, как и в других языках программирования, в скрипте можно применять команды условных и безусловных переходов (b
, t
, и T
), имеются также команды прерывания работы (q
и Q
). Некоторые команды воздействуют не только на этап обработки строки, но и на другие этапы. Кроме того, внутри скрипта можно ввести ещё одну или несколько строк из входного потока (как на первом этапе).
3. Вывод буфера в выходной поток
После завершения работы скрипта sed выводит содержимое буфера в выходной поток. Однако, это далеко не всегда необходимо, если это не нужно, можно использовать опцию -n
, которая блокирует вывод буфера. Кроме того, на этом же этапе происходит вывод и некоторой другой информации, если в скрипте выполнились команды a
, c
или i
. Эти команды тоже выводят информацию в выходной поток, но не во время исполнения, а на этом этапе. Существуют три команды (d
, D
и Q
), которые тоже подавляют вывод буфера на этом этапе.
Фильтр строк
В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:
- Задать ограничение на номера строк, которые нужно обрабатывать.
- Указать фильтр, соответствующие которому строки нужно обработать.
Указание номера одной строки, которую нужно обработать:
$ sed '2s/шаблон/замена/g' inputFile
Указание диапазона строк, которые нужно обработать:
$ sed '2,4s/шаблон/замена/g' inputFile
Обработать только строки, соответствующие фильтру:
$ sed '/фильтр/s/шаблон/замена/g' inputFile
Удаление строк
Команда d
(от delete) подавляет вывод строки в выходной поток по номеру или по шаблону.
Удалить третью строку (подавить вывод в буфер на третьем этапе)
$ sed '3d' inputFile
Удалить строки, начиная с заданной — и до конца файла
$ sed '3,$d' inputFile
Строки можно удалять и по шаблону
$ sed '/шаблон/d' inputFile
При вызове команды d
можно указывать пару шаблонов — будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними.
$ sed '/первый/,/третий/d' inputFile
Вставка строк
Можно вставлять данные в выходной поток на третьем этапе, используя команды i
(от insert) и a
(от append).
- команда
i
добавляет новую строку перед заданной - команда
a
добавляет новую строку после заданной
Вызовем команды i
и a
, указав номер строки, перед/после которой надо вставить новую строку.
$ sed '3i\Это новая строка' inputFile
$ sed '5a\Это новая строка' inputFile
Замена строк
Команда c
(от change) позволяет изменить содержимое целой строки текста в потоке данных. При её вызове нужно указать номер строки, вместо которой в поток надо добавить новые данные:
$ sed '3c\Это измененная строка' inputFile
Если воспользоваться при вызове команды шаблоном в виде обычного текста или регулярного выражения, заменены будут все соответствующие шаблону строки:
$ sed '/шаблон/c\Новая строка вместо старых' inputFile
Замена символов
Команда y
работает с отдельными символами, заменяя их в соответствии с переданными ей при вызове данными:
$ sed 'y/1234/5678/' inputFile
Регулярные выражения
Редактор sed поддерживает два типа регулярных выражений: базовый (BRE — basic regular expressions) и расширенный (ERE — extended regular expressions). По умолчанию sed использует базовый тип регулярных выражений.
В BRE распознаются следующие метасимволы:
^ $ . [ ] *
Все другие символы расцениваются как литералы. В ERE добавлены следующие метасимволы (и связанные с ними функции):
( ) { } ? + |
Тем не менее, символы «(», «)», «{» и «}» в BRE обрабатываются как метасимволы, если они экранированы обратным слешом; в то время как в ERE постановка перед любыми метасимволами обратного слеша приводит к тому, что они трактуются как литералы.
Опция -r редактора sed позволяет использовать расширенные регулярные выражения.
Опции редактора
Опция -n подавляет вывод буфера на третьем этапе. Чтобы получить вывод нужно специальное указание, например, команда p
(от print).
Опция -e позволяет выполнить несколько команд, например:
$ sed -e 's/шаблон1/замена1/' -e 's/шаблон2/замена2/' inputFile
Опция -f позволяет выполнить большое количество команд, записанных в файл:
$ sed -f commandFile inputFile
# этот скрипт изменит все строчные гласные буквы на заглавные s/a/A/g s/e/E/g s/i/I/g s/o/O/g s/u/U/g
Опция -i позволяет записать результат работы в исходный файл. Можно указать суффикс, с которым будет сохранен исходный файл (можно использовать, если нет уверенности в правильности редактирования).
$ sed -i.src '/шаблон/d' inputFile
Модификаторы команды замены
Кроме модификатора g
, который позволяет заменить все вхождения шаблона, есть еще модификаторы p
, w
, e
, i
и число
.
Модификатор p
(от print) применяется только с опцией -n
, которая как раз блокирует вывод результата в выходной поток. Модификатор w
(от write) позволяет записывать результаты обработки текста в указанный файл. Модификатор e
позволяет указать команду шелла в качестве замены
. Модификатор i
делают процесс замены нечувствительным к регистру символов. Модификатор число
указывает, какое по счету совпадение подлежит замене.
Несколько примеров использования
Замена без использования модификатора g
:
$ echo 'кот этот, был самый обычный кот' | sed 's/кот/котенок/' котенок этот, был самый обычный кот
А теперь с модификатором глобальной замены:
$ echo 'кот этот, был самый обычный кот' | sed 's/кот/котенок/g' котенок этот, был самый обычный котенок
Заключить все слова в скобки (&
или \0
означает найденное совпадение с шаблоном):
$ echo 'глупый пингвин робко прячет' | sed 's/[^ ]*/(&)/g' (глупый) (пингвин) (робко) (прячет)
Поменять слова местами:
$ echo 'глупый пингвин' | sed 's/\([а-я]*\) \([а-я]*\)/\2 \1/' пингвин глупый
\(…\)
— вот так странно работают регулярные выражения BRE.
Заменяем второе слово в строке (число после последнего разделителя указывает, какое по счету совпадение подлежит замене):
$ echo очень глупый пингвин | sed 's/[а-я]*/хороший/2' очень хороший пингвин
Заменяем второе и все следующие слова:
$ echo очень глупый пингвин | sed 's/[а-я]*/хороший/2g' очень хороший хороший
Удалить все слова, кроме первого:
$ echo 'очень глупый пингвин' | sed 's/[^ ]*//2g' очень
Показать строки со 2 по 4:
$ cat unix.txt The Unix operating system was pioneered by Ken Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in the design of the Unix system was to create an environment that promoted efficient program development. $ sed -n '2,4p' unix.txt Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in the design of the Unix system was to create an
Удалить строки со 2 по 4:
$ sed '2,4d' unix.txt The UNIX operating system was pioneered by Ken environment that promoted efficient program development.
Удалить все строки, содержащие текст «Unix»:
$ sed '/Unix/d' unix.txt Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in environment that promoted efficient program development.
Удалить последние три символа из каждой строки:
$ sed 's/...$//' unix.txt The Unix operating system was pioneered by Thompson and Dennis Ritchie at Bell Laborator in the late 1960s. One of the primary goals the design of the Unix system was to create environment that promoted efficient prog developme
Добавить три *
в начало каждой строки:
$ sed 's/^/***/' unix.txt ***The Unix operating system was pioneered by Ken ***Thompson and Dennis Ritchie at Bell Laboratories ***in the late 1960s. One of the primary goals in ***the design of the Unix system was to create an ***environment that promoted efficient program ***development.
Удалить строки, содержащие цифры:
$ sed '/[0-9]/d' unix.txt The Unix operating system was pioneered by Ken Thompson and Dennis Ritchie at Bell Laboratories the design of the Unix system was to create an environment that promoted efficient program development.
Заменить первое вхождение «Unix» на «UNIX» во всех строках, содержащих «design»
$ sed '/design/s/Unix/UNIX/' unix.txt The Unix operating system was pioneered by Ken Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in the design of the UNIX system was to create an environment that promoted efficient program development.
Справка по использованию редактора
$ sed --help Использование: sed [ПАРАМЕТР]… {только-сценарий-если-нет-другого-сценария} [входной-файл]… -n, --quiet, --silent выключить автоматическую печать образца --debug комментировать выполнение программы -e script, --expression=сценарий добавить сценарий в исполняемые команды -f script-file, --file=файл-сценария добавить содержимое файла-сценария в исполняемые команды --follow-symlinks переходить по символьным ссылкам при обработке на месте -i[СУФФИКС], --in-place[=СУФФИКС] править файлы на месте (создаёт копию, если указан СУФФИКС) -l N, --line-length=N задать желаемую длину до переноса строки для команды «l» --posix отключить все расширения GNU -E, -r, --regexp-extended использовать в сценарии расширенные регулярные выражения (для переносимости используйте -E (POSIX) -s, --separate рассматривать файлы раздельно, а не в виде одного длинного непрерывного потока --sandbox работать в режиме «песочницы» (отключает команды e/r/w) -u, --unbuffered загружать минимальный объём данных из входных файлов и чаще сбрасывать выходные буферы на диск -z, --null-data разделять строки символами NUL --help показать эту справку и выйти --version показать информацию о версии и выйти Если не указан параметр -e, --expression, -f или --file, то в качестве интерпретируемого сценария sed берётся первый необязательный аргумент. Все оставшиеся аргументы являются именами входных файлов; если входные файлы не указаны, тогда читается стандартный ввод.