Потоковый редактор sed

12.02.2018

Теги: LinuxRegExpКомандаРедакторШаблон

Редактор 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 берётся первый необязательный аргумент.
Все оставшиеся аргументы являются именами входных файлов; если входные
файлы не указаны, тогда читается стандартный ввод.

Поиск: Linux • RegExp • Команда • Редактор • Шаблон • sed

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.