Парадигма | написание сценариев |
---|---|
Разработано | Ли Э. Макмахон |
Впервые появился | 1974 ( 1974 ) |
Язык реализации | С |
Под влиянием | |
ред | |
Под влиянием | |
Perl , AWK |
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 sed и в настоящее время поддерживаемый Рене Ребе . minised использовался проектом GNU до тех пор, пока проект GNU не написал новую версию sed на основе новой библиотеки регулярных выражений GNU. Текущая версия minised содержит некоторые расширения BSD sed, но не так многофункциональна , как GNU sed. Ее преимущество в том, что она очень быстрая и использует мало памяти. Она используется во встраиваемых системах и является версией sed, поставляемой с Minix . [5]
sed — это утилита для обработки текста, ориентированная на строки: она считывает текст, строку за строкой, из входного потока или файла, во внутренний буфер, называемый пространством шаблонов . Каждая прочитанная строка запускает цикл . К пространству шаблонов sed применяет одну или несколько операций, которые были указаны с помощью скрипта sed . sed реализует язык программирования с примерно 25 командами , которые определяют операции над текстом. Для каждой входной строки после запуска скрипта sed обычно выводит пространство шаблонов (строку, измененную скриптом) и начинает цикл снова со следующей строки. Другие поведения конца скрипта доступны с помощью опций sed и команд скрипта, например, d
для удаления пространства шаблонов, q
для выхода, N
для немедленного добавления следующей строки в пространство шаблонов и т. д. Таким образом, скрипт sed соответствует телу цикла, который проходит по строкам потока, где сам цикл и переменная цикла (текущий номер строки) неявны и поддерживаются sed.
Скрипт sed может быть указан в командной строке ( -e
опция) или прочитан из отдельного файла ( -f
опция). Команды в скрипте sed могут принимать необязательный адрес в виде номеров строк или регулярных выражений . Адрес определяет, когда команда будет запущена. Например, 2d
запустит d
команду (delete) только на второй строке ввода (выведя все строки, кроме второй), в то время как /^ /d
удалит все строки, начинающиеся с пробела. Отдельный специальный буфер, hold space , может использоваться несколькими командами sed для хранения и накопления текста между циклами. Командный язык sed имеет только две переменные («hold space» и «pattern space») и GOTO -подобную функциональность ветвления; тем не менее, язык является полным по Тьюрингу [6] [7] , и существуют эзотерические скрипты sed для таких игр, как sokoban , arkanoid , [8] chess , [9] и tetris . [10]
Основной цикл выполняется для каждой строки входного потока, оценивая скрипт sed для каждой строки входных данных. Каждая строка скрипта sed представляет собой пару шаблон-действие, указывающую, какой шаблон сопоставить и какое действие выполнить, что можно преобразовать в условный оператор . Поскольку основной цикл, рабочие переменные (пространство шаблона и пространство удержания), потоки ввода и вывода и действия по умолчанию (копирование строки в пространство шаблона, печать пространства шаблона) являются неявными, можно писать краткие однострочные программы . Например, программа sed, заданная следующим образом:
10кв
напечатает первые 10 строк ввода, а затем остановится.
Следующий пример показывает типичное и наиболее распространенное использование sed: подстановка. Это использование действительно было изначальной мотивацией для sed: [4]
sed 's/regexp/replacement/g' Имя_входного_файла > Имя_выходного_файла
В некоторых версиях sed выражение должно предваряться , чтобы -e
указать, что за ним следует выражение. s
обозначает замену, а g
обозначает глобальное, что означает, что все совпадающие вхождения в строке будут заменены. Регулярное выражение (т. е. шаблон), которое нужно найти, помещается после первого разделительного символа (здесь косая черта), а замена следует за вторым символом. Косая черта ( /
) — это общепринятый символ, происходящий от символа для «search» в ed, но любой другой может быть использован для того, чтобы сделать синтаксис более читабельным, если он не встречается в шаблоне или замене; это полезно, чтобы избежать « синдрома наклонной зубочистки ».
Команда подстановки, которая берет свое начало в поиске и замене в ed, реализует простой синтаксический анализ и шаблонизацию . regexp
Обеспечивает как сопоставление с образцом, так и сохранение текста через подвыражения, в то время как может быть либо текстом в буквальном смысле, либо строкой replacement
формата, содержащей символы &
для "полного совпадения" или специальные управляющие последовательности для n -го сохраненного подвыражения. Например, заменяет все вхождения "cat" или "dog" на "cats" или "dogs", не дублируя существующее "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 часто используется как фильтр в конвейере :
$ generateData | sed 's/x/y/g'
То есть, программа типа "generateData" генерирует данные, а затем sed делает небольшое изменение, заменяя x на y . Например:
$ echo xyz xyz | sed 's/x/y/g' yyz yyz
[примечания 1]
Часто бывает полезно поместить несколько команд sed, по одной команде на строку, в файл скрипта, например subst.sed
, а затем использовать -f
опцию для запуска команд (например s/x/y/g
) из файла:
sed -f subst.sed Имя_входного_файла > Имя_выходного_файла
В файл скрипта можно поместить любое количество команд, а использование файла скрипта также позволяет избежать проблем с экранированием оболочки или подстановками.
Такой файл сценария можно сделать исполняемым непосредственно из командной строки, добавив к нему " shebang line", содержащую команду sed, и назначив файлу разрешение на исполнение. Например, subst.sed
можно создать файл с содержимым:
#!/bin/sed -f с / х / у / г
Затем текущий пользователь может сделать файл исполняемым с помощью chmod
команды:
chmod u+x подстановка.sed
Затем файл можно запустить непосредственно из командной строки:
subst.sed ИмяФайлаВвода > ИмяФайлаВывода
Опция -i
, представленная в GNU sed, позволяет редактировать файлы на месте (фактически, временный выходной файл создается в фоновом режиме, а затем исходный файл заменяется временным файлом). Например:
sed -i 's/abc/def/' имя_файла
# преобразовать входной текстовый поток в "Hello, world!" s / .* / Hello, world! / q
Этот скрипт "Hello, world!" находится в файле (например, script.txt) и вызывается с помощью sed -f script.txt inputFileName
, где "inputFileName" — это входной текстовый файл. Скрипт изменяет строку "inputFileName" № 1 на "Hello, world!" и затем завершает работу, печатая результат до выхода sed. Все входные строки после строки № 1 не считываются и не печатаются. Таким образом, единственным выводом является "Hello, world!".
В этом примере подчеркиваются многие ключевые характеристики sed:
#
символа).s
(substitute) — самая важная команда sed.q
(выйти)..*
(ноль или более любых символов).Ниже приведены различные скрипты sed; их можно выполнить, передав в качестве аргумента sed, или поместить в отдельный файл и выполнить с помощью -f
, или сделав сам скрипт исполняемым.
Чтобы заменить любое вхождение определенного слова в файле на «REDACTED», например, пароль IRC, и сохранить результат:
$ sed -i "s/вашпароль/УДАЛЕНО/" ./status.chat.log
Чтобы удалить любую строку, содержащую слово «yourword» ( адрес — «/yourword/»):
/ ваше слово / д
Чтобы удалить все вхождения слова «yourword»:
s / ваше слово // г
Чтобы удалить два слова из файла одновременно:
s / первое слово // g s / второе слово // g
Чтобы выразить предыдущий пример в одной строке, например, при вводе в командной строке, можно объединить две команды точкой с запятой:
$ sed "s/firstword//g; s/secondword//g" имя_вводного_файла
В следующем примере sed, который обычно работает только с одной строкой, удаляет переводы строк из предложений, где вторая строка начинается с одного пробела. Рассмотрим следующий текст:
Это моя собака, которого зовут Фрэнк.Это моя рыба,которого зовут Джордж.Это моя коза, чье имя Адам.
Скрипт sed ниже преобразует текст выше в следующий текст. Обратите внимание, что скрипт влияет только на строки ввода, начинающиеся с пробела:
Это моя собака, ее зовут Фрэнк.Это моя рыба,которого зовут Джордж.Это мой козел, его зовут Адам.
Сценарий такой:
Н с / \н / / П Д
Это объясняется следующим образом:
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. Ли Макмахон взялся написать ее и вскоре предвидел, что конца этому семейству не будет: g/re/d, g/re/a и т. д. По мере развития его концепции она превратилась в sed…