sed («редактор потока») — это утилита Unix , которая анализирует и преобразует текст, используя простой и компактный язык программирования. Он был разработан с 1973 по 1974 год Ли Э. МакМахоном из Bell Labs [ 1] и сегодня доступен для большинства операционных систем. [2] sed был основан на функциях сценариев интерактивного редактора ed («редактор», 1971 г.) и более раннего qed («быстрый редактор», 1965–66 гг.). Это был один из первых инструментов для поддержки регулярных выражений , который до сих пор используется для обработки текста, особенно с помощью команды подстановки. Популярные альтернативные инструменты для манипулирования строками открытого текста и «потокового редактирования» включают AWK и Perl .
Впервые появившаяся в версии 7 Unix , [3] sed — одна из первых команд Unix, созданных для обработки файлов данных в командной строке. Она возникла как естественный преемник популярной команды grep . [4] Первоначальной мотивацией был аналог grep (g/re/p) для замены, отсюда и «g/re/s». [3] Предвидя, что для каждой команды также возникнут дополнительные программы специального назначения, такие как g/re/d, МакМахон написал универсальный построчно-ориентированный потоковый редактор, который стал sed. [4] Синтаксис sed, в частности использование /
для сопоставления с образцом и s///
для замены, возник в ed , предшественнике sed, который широко использовался в то время, [4] и синтаксис регулярных выражений повлиял на другие языки. , особенно ECMAScript и Perl . Позже был разработан более мощный язык AWK , который функционировал как двоюродный брат, позволяя выполнять мощную обработку текста с помощью сценариев оболочки . sed и AWK часто называют прародителями и вдохновителями Perl, они повлияли на синтаксис и семантику Perl, особенно на операторы сопоставления и замены.
В GNU sed добавлено несколько новых функций, включая редактирование файлов на месте. Super-sed — это расширенная версия sed, включающая регулярные выражения, совместимые с Perl . Другой вариант sed — minised , первоначально созданный методом реверс-инжиниринга из 4.1BSD, созданный Эриком С. Рэймондом и в настоящее время поддерживаемый Рене Ребе . minised использовался проектом GNU до тех пор, пока проект GNU не написал новую версию sed на основе новой библиотеки регулярных выражений GNU. Текущая мини-версия содержит некоторые расширения для BSD sed, но не так многофункциональна, как GNU sed. Его преимущество в том, что он очень быстрый и использует мало памяти. [ необходима цитация ] Он используется во встроенных системах и представляет собой версию sed, поставляемую с Minix . [ нужна цитата ]
sed — это утилита построчно-ориентированной обработки текста: она считывает текст построчно из входного потока или файла во внутренний буфер, называемый пространством шаблонов . Каждое чтение строки запускает цикл . К пространству шаблонов sed применяет одну или несколько операций, указанных в сценарии sed . sed реализует язык программирования , содержащий около 25 команд , определяющих операции с текстом. Для каждой входной строки после запуска сценария sed обычно выводит пространство шаблонов (строку, измененную сценарием) и снова начинает цикл со следующей строки. Другие варианты поведения в конце сценария доступны через параметры sed и команды сценария, например, d
для удаления пространства шаблонов, q
выхода, N
немедленного добавления следующей строки в пространство шаблонов и т. д. Таким образом, сценарий sed соответствует телу цикла, который проходит по строкам потока, где сам цикл и переменная цикла (текущий номер строки) являются неявными и поддерживаются sed.
Сценарий sed можно указать в командной строке ( -e
опция) или прочитать из отдельного файла ( -f
опция). Команды в сценарии sed могут принимать необязательный адрес в виде номеров строк или регулярных выражений . Адрес определяет, когда выполняется команда. Например, команда (удалить) 2d
будет запущена только d
для второй строки ввода (печать всех строк, кроме второй), при этом /^ /d
будут удалены все строки, начинающиеся с пробела. Отдельный специальный буфер, пространство хранения , может использоваться несколькими командами sed для хранения и накопления текста между циклами. командный язык sed имеет только две переменные («пространство хранения» и «пространство шаблонов») и функциональность ветвления, подобную GOTO ; тем не менее, язык является полным по Тьюрингу , [5] [6] и существуют эзотерические sed-скрипты для таких игр, как сокобан , арканоид , [7] шахматы , [8] и тетрис . [9]
Основной цикл выполняется для каждой строки входного потока, оценивая сценарий sed в каждой строке входного потока. Каждая строка сценария sed представляет собой пару шаблон-действие, указывающую, какой шаблон сопоставить и какое действие выполнить, что можно преобразовать в условный оператор . Поскольку основной цикл, рабочие переменные (пространство шаблонов и пространство хранения), потоки ввода и вывода, а также действия по умолчанию (копирование строки в пространство шаблонов, печать пространства шаблонов) неявны, можно писать краткие однострочные программы . Например, программа sed, заданная:
10q
напечатает первые 10 строк ввода, а затем остановится.
В следующем примере показано типичное и наиболее распространенное использование sed: подстановка. Это использование действительно было первоначальной мотивацией для sed: [4]
sed 's/regexp/replacement/g' имя_входного_файла > имя_выходного_файла
В некоторых версиях sed перед выражением должен стоять знак, -e
указывающий, что выражение следует за ним. Символ s
означает замену, а g
символ — глобальный, что означает, что все совпадающие вхождения в строке будут заменены. Регулярное выражение (т. е. шаблон), по которому осуществляется поиск, помещается после первого символа-разделителя (здесь косая черта), а замена следует за вторым символом. Косая черта ( /
) — это общепринятый символ, происходящий от символа «поиск» в ed, но можно использовать любой другой, чтобы сделать синтаксис более читабельным, если он не встречается в шаблоне или замене; это полезно, чтобы избежать « синдрома наклоненной зубочистки ».
Команда подстановки, берущая начало в search-and-replace в ed, реализует простой синтаксический анализ и создание шаблонов . Обеспечивает regexp
сопоставление с образцом и сохранение текста с помощью подвыражений, при этом the replacement
может быть либо буквальным текстом, либо строкой формата, содержащей символы для «полного совпадения» , &
либо специальные escape-последовательности для n- го сохраненного подвыражения. Например, заменяет все вхождения слов «кошка» или «собака» на «кошки» или «собаки», не дублируя существующую букву «s»: это первое (и единственное) сохраненное подвыражение в регулярном выражении и в формате строка заменяет это в выводе.\1
\9
sed -r "s/(cat|dog)s?/\1s/g"
(cat|dog)
\1
Помимо замены, возможны и другие формы простой обработки с использованием около 25 команд sed. Например, в следующем примере команда d используется для фильтрации строк, содержащих только пробелы или содержащие только символ конца строки:
sed '/^ *$/d' имя_входного_файла
В этом примере используются некоторые из следующих метасимволов регулярных выражений (sed поддерживает полный диапазон регулярных выражений):
^
соответствует началу строки.$
соответствует концу строки.*
соответствует нулю или более вхождению предыдущего символа.+
?
соответствует нулю или одному вхождению предыдущего символа..
соответствует ровно одному символу.Возможны сложные конструкции sed, позволяющие ему служить простым, но узкоспециализированным языком программирования . Например, потоком управления можно управлять с помощью метки ( двоеточие, за которым следует строка) и инструкции ветвления b
, а также условного ветвления t
. Инструкция, b
за которой следует допустимое имя метки, переведет обработку на команду, следующую за этой меткой. Инструкция t
сделает это только в том случае, если с момента предыдущей t
(или запуска программы, в случае первой t
встречи) произошла успешная замена. Дополнительно {
инструкция запускает подпоследовательность команд (вплоть до совпадения }
); в большинстве случаев это будет обусловлено шаблоном адреса.
В Unix sed часто используется в качестве фильтра в конвейере :
$ генерировать данные | sed 's/x/y/g'
То есть такая программа, как «generateData», генерирует данные, а затем sed вносит небольшое изменение, заменяя x на y . Например:
$ эхо xyz xyz | sed 's/x/y/g' yyz yyz
[примечания 1]
Часто бывает полезно поместить несколько команд sed, по одной команде в строке, в файл сценария, например subst.sed
, а затем использовать -f
опцию для запуска команд (например, s/x/y/g
) из файла:
sed -f subst.sed имя_входного_файла > имя_выходного_файла
В файл сценария можно поместить любое количество команд, а использование файла сценария также позволяет избежать проблем с экранированием оболочки или подстановками.
Такой файл сценария можно сделать исполняемым непосредственно из командной строки, добавив к нему « строку shebang », содержащую команду sed, и назначив файлу разрешение на выполнение. Например, файл subst.sed
может быть создан с содержимым:
#!/bin/sed -f s / x / y / g
Затем файл может быть сделан исполняемым текущим пользователем с помощью chmod
команды:
chmod u+x subst.sed
Затем файл можно выполнить непосредственно из командной строки:
subst.sed имя_входного_файла > имя_выходного_файла
Опция -i
, представленная в GNU sed, позволяет редактировать файлы на месте (фактически в фоновом режиме создается временный выходной файл, а затем исходный файл заменяется временным файлом). Например:
sed -i 's/abc/def/' имя_файла
# конвертируем входной текстовый поток в "Hello, world!" s /.*/ Привет , мир! / д
Это «Привет, мир!» сценарий находится в файле (например, script.txt) и вызывается с помощью sed -f script.txt inputFileName
, где «inputFileName» — это входной текстовый файл. Скрипт меняет строку №1 «inputFileName» на «Hello, world!» а затем завершает работу, печатая результат перед завершением работы sed. Любые строки ввода после строки №1 не читаются и не печатаются. Таким образом, единственный вывод — «Привет, мир!».
В примере подчеркиваются многие ключевые характеристики sed:
#
).s
(замена) является наиболее важной командой sed.q
(quit)..*
(ноль или более любых символов).Ниже приведены различные сценарии sed; их можно выполнить, передав в качестве аргумента sed, или поместить в отдельный файл и выполнить через него, -f
или сделав сам скрипт исполняемым.
Чтобы заменить любой экземпляр определенного слова в файле на «УДАЛЕНО», например пароль IRC, и сохранить результат:
$ sed -i "s/вашпароль/УДАЛЕНО/" ./status.chat.log
Чтобы удалить любую строку, содержащую слово «ваше слово» ( адрес — «/ваше слово/»):
/ твое слово / д
Чтобы удалить все вхождения слова «ваше слово»:
с / ваше слово // г
Чтобы удалить два слова из файла одновременно:
s / первое слово // g s / второе слово // g
Чтобы выразить предыдущий пример в одной строке, например, при вводе в командной строке, можно объединить две команды точкой с запятой:
$ sed "s/firstword//g; s/ Secondword//g" inputFileName
В следующем примере sed, который обычно работает только с одной строкой, удаляет символы новой строки из предложений, где вторая строка начинается с одного пробела. Рассмотрим следующий текст:
Это моя собака, которого зовут Фрэнк.Это моя рыба,которого зовут Джордж.Это моя коза, которого зовут Адам.
Приведенный ниже сценарий sed превратит приведенный выше текст в следующий текст. Обратите внимание, что скрипт влияет только на строки ввода, начинающиеся с пробела:
Это моя собака, которую зовут Фрэнк.Это моя рыба,которого зовут Джордж.Это мой козел, которого зовут Адам.
Сценарий:
Н s / \n / / P D
Это объясняется так:
N
) добавить следующую строку в пространство шаблонов;s/\n / /
) найти новую строку, за которой следует пробел, заменить одним пробелом;P
) напечатайте верхнюю строку пространства шаблонов;D
) удалите верхнюю строку из пространства шаблонов и снова запустите скрипт.Это можно выразить в одной строке через точку с запятой:
sed ' 'имя_входного_файлаN; s/\n / /; P; D
Несмотря на простоту и ограниченность, sed является достаточно мощным для большого количества целей. Для более сложной обработки вместо этого используются более мощные языки, такие как AWK или Perl . Они особенно используются при преобразовании строки более сложным способом, чем извлечение регулярного выражения и замена шаблона, хотя в принципе возможны сколь угодно сложные преобразования с использованием буфера хранения.
И наоборот, для более простых операций используются специализированные утилиты Unix, такие как grep (печать строк, соответствующих шаблону), head (печать первой части файла), Tail (печать последней части файла) и tr (перевод или удаление символов). зачастую предпочтительнее. Для решения конкретных задач такие специализированные утилиты обычно проще, понятнее и быстрее, чем более общее решение, такое как sed.
Команды и синтаксис ed/sed продолжают использоваться в дочерних программах, таких как текстовые редакторы vi и vim . Аналогом ed/sed является sam /ssam, где sam — редактор Plan 9 , а ssam — потоковый интерфейс к нему, обеспечивающий функциональность, аналогичную sed.
s/x/y/g
нет никакой двусмысленности, поэтому generateData | sed s/x/y/g
работает корректно. Однако кавычки обычно включаются для ясности и часто необходимы, особенно для пробелов (например, 's/x x/y y/'
). Чаще всего используются одинарные кавычки, чтобы оболочка не интерпретировала их $
как переменную оболочки. Двойные кавычки используются, например "s/$1/$2/g"
, чтобы позволить оболочке заменить аргумент командной строки или другую переменную оболочки.Спустя некоторое время на замену возникла потребность в другой специальной программе — gres: g/re/s. Ли МакМэхон взялся написать ее и вскоре предвидел, что семейству не будет конца: г/ре/д, г/ре/а и т. д. По мере развития его концепции она стала сед…