Sed отсутствуют входные файлы

Обновлено: 06.07.2024

Сценарий состоит из одной или нескольких инструкций правки, введенных в командной строке.

Утилита sed представляет собой потоковый редактор, который выполняет чтение одного или нескольких текстовых файлов, вносит изменения согласно указанным командам правки и записывает результаты в стандартный поток вывода.

Примечание. На данную утилиту распространяются условия общедоступной лицензии GNU Public License (GPL). Она предназначена для использования в системах разработки программ.

Команды sed обычно хранятся в программном файле ( файл_сценария ), однако простые команды sed можно вводить через командную строку. По умолчанию sed копирует файлы из списка файлов в стандартный поток вывода с правкой строк. В принципе, существует один входной файл, который представляет собой конкатенацию всех указанных входных файлов.

Выбор строк для правки выполняется на основе их положения во входном файле или путем сопоставления с шаблоном. Если файлы в списке отсутствуют, используются входные данные из стандартного потока ввода (это единственный случай использования стандартного потока ввода). Утилита sed сначала считывает все команды правки из всех указанных источников и помещает их во внутреннюю таблицу в определенном порядке. Далее выполняется обработка (сцепленного) входного файла следующим образом:

Выполняется считывание одной строки из входного файла с копированием в пространство шаблонов (рабочую область).

Для каждой команды, выбирающей строку, пространство шаблонов обрабатывается в соответствии с инструкциями команды правки с циклическим помещением результата в пространство шаблонов.

После проверки всех команд на соответствие пространству шаблонов выполняется запись пространства шаблонов в стандартный поток вывода при условии, что значение -n не определено. В этот момент пространство шаблонов может содержать ни одной, одну или несколько строк.

Далее содержимое пространства шаблонов удаляется.

Процедура повторяется с шага 1 до полного завершения операции чтения и обработки (сцепленного) входного файла.

Сценарий состоит из команд правки в следующем формате (по одной в каждой строке):

[ адрес[,адрес]]функция[аргументы]

Сценарий команд правки можно указать в командной строке или использовать сценарий из файла, определенного аргументом файл_сценария.

При использовании значений по умолчанию утилита sed циклически копирует строку ввода в пространство шаблонов (при отсутствии данных после выполнения команды D ), последовательно применяет все команды, адреса которых указывают на это пространство шаблонов, и при завершении сценария копирует пространство шаблонов в стандартный поток вывода (если не используется опция -n ) с последующим удалением этого пространства.

При выполнении некоторых команд для полного или частичного сохранения пространства_шаблонов используется пространство_удержания с последующим извлечением данных. Пространство_шаблонов и пространство_удержания имеют ограничение по размеру – 20 КБ.

Возможные варианты адреса:

десятичное число, соответствующее общему количеству строк ввода в файлах;

маркер $ , который относится к последней строке ввода;

Командная строка без адреса указывает на все пространства шаблонов. Командная строка с одним адресом указывает на все пространства шаблонов, соответствующие этому адресу.

Командная строка с двумя адресами указывает на включающий предельные значения диапазон с первого пространства шаблонов, соответствующего первому адресу, до следующего пространства шаблонов, соответствующего второму адресу. (Если номер строки второго адреса меньше или равен номеру первой выбранной строки, будет выбрана только первая строка.) Начиная с первой строки после выбранного диапазона, утилита sed выполняет повторный поиск первого адреса. Далее процесс повторяется.

Для применения команд правки к невыбранным пространствам шаблонов можно использовать символ отрицания ( ! ). Для получения дополнительной информации см. раздел "Команды правки" далее.

Регулярные выражения

Утилита sed использует базовые регулярные выражения ( RE ) со следующими дополнениями:

В адресе контекста конструкция \ ?RE? (где ? является любым символом) отображается в формате / RE / . Обратите внимание на то, что в адресе контекста \xabc\xdefx второй символ x обозначает сам себя, поэтому регулярное выражение будет иметь вид abcxdef .

Управляющая последовательность \n соответствует символу новой строки newline , встроенному в пространство шаблонов.

Точка ( . ) соответствует любому символу, кроме последнего символа новой строки newline в пространстве шаблонов.

Команды правки

В следующем списке функций максимальное число допустимых адресов для каждой функции определено одним из аргументов: [ 0addr ], [ 1addr ] или [ 2addr ], что соответствует отсутствию адресов, одному или двум адресам соответственно. Аргумент текст состоит из одной или нескольких строк. Перед каждым встроенным в текст символом новой строки newline должна стоять обратная косая черта. Другие обратные косые черты в тексте обрабатываются как аналогичные символы в строке замены команды правки s ; они используются для предотвращения отбрасывания начальных пробелов blank в каждой строке сценария.

Команды правки r и w используют дополнительный параметр rfile (или wfile ), отделенный от буквы команды нулем или несколькими пробелами blank .

Аргументы rfile или wfile завершают командную строку. Каждый аргумент wfile создается до начала обработки. В сценарии может использоваться до десяти отдельных аргументов wfile.

При выполнении команд правки b , r , s , t , w , y , ! и : используются дополнительные аргументы. Далее кратко представлены аргументы, отделяемые от команд пробелами:

[2 addr ] список_команд
>

Выполнять список_команд только в том случае, если выбрано пространство шаблонов. (Следует учесть, что конечный символ > должен являться первым непробельным символом в строке.)

[1 addr ] a\
текст

Записать текст в стандартный поток вывода после записи пространства шаблонов.

[2 addr ] b метка

Перейти к команде : (двоеточие) с аргументом метка . Если значение аргумента метка не указано, перейти к концу сценария.

[2 addr ] c\
текст

Удалить пространство шаблонов. При использовании 0 или 1 адреса, либо в конце диапазона из 2 адресов поместить текст в вывод.

[2 addr ] d

Удалить пространство шаблонов и запустить следующий цикл.

[2 addr ] D

Удалить начальный сегмент пространства шаблонов до первого символа новой строки newline и запустить новый цикл.

[2 addr ] g

Заменить содержимое пространства шаблонов содержимым пространства удержания.

[2 addr ] G

Добавить содержимое пространства удержания в пространство шаблонов.

[2 addr ] h

Заменить содержимое пространства удержания содержимым пространства шаблонов.

[2 addr ] H

Добавить содержимое пространства шаблонов в пространство удержания.

[1 addr ] i\
текст

Записать текст в стандартный поток вывода до записи пространства шаблонов.

[2 addr ] l

Представить пространство шаблонов в стандартном потоке вывода в однозначном формате. Непечатаемые символы отображаются как пары шестнадцатеричных цифр с предшествующей обратной косой чертой. При этом применяются следующие исключения:

Обозначение

alert (символ звукового сигнала)

backslash (обратная косая черта)

carriage return (символ возврата каретки)

form-feed (символ перевода страницы)

vertical tab (символ вертикальной табуляции)

Длинные линии сворачиваются; длина, при которой выполняется сворачивание, не определена, но должна соответствовать особенностям устройства вывода.

[2 addr ] n

Копировать пространство шаблонов в стандартный поток вывода и заменить пространство шаблонов следующей строкой ввода.

[2 addr ] N

Добавить следующую строку ввода в пространство шаблонов с разделением добавленного и исходного материала посредством символа новой строки newline . Обратите внимание на изменение номера строки.

[2 addr ] p

Копировать (вывести) пространство шаблонов в стандартный поток вывода.

[2 addr ] P

Копировать (вывести) пространство шаблонов до первого символа новой строки newline в стандартный поток вывода.

[1 addr ] q

Перейти к концу сценария и выполнить выход без запуска нового цикла.

[1 addr ] r rfile

Считать содержимое файла rfile. Содержимое помещается в вывод перед считыванием следующей строки ввода.

[2 addr ] s/ регулярное_выражение / строка_замены / флажки

Выполнить подстановку строки_замены для экземпляров регулярного_выражения в пространстве шаблонов. Вместо символа / можно использовать любой символ. Возможными значениями аргумента флажки являются нуль или следующие варианты:

n = от 1 до 512. Подстановка n-го вхождения только для регулярного_выражения, найденного в пространстве шаблонов.

Выполнить глобальную подстановку для всех неперекрывающихся экземпляров регулярного_выражения , а не только для первого экземпляра. Если указаны значения g и n , более высокий приоритет имеет значение g .

Вывести пространство шаблонов, если была произведена замена.

Добавить (записать) пространство шаблонов в файл wfile, если была произведена замена.

[2 addr ] t метка

Выполнить проверку; перейти к команде : (двоеточие) с аргументом метка , если с момента последнего считывания строки ввода или выполнения команды t были произведены какие-либо замены. Если значение аргумента метка не указано, то перейти к концу сценария.

[2 addr ] w wfile

Добавить (записать) пространство шаблонов в файл wfile.

[2 addr ] x

Поменять местами содержимое пространства шаблонов и пространства удержания.

[2 addr ] y/ строка1 / строка2 /

Заменить все вхождения элементов упорядочения в строке строка1 соответствующим элементом упорядочения в строке строка2. Длины строк строка1 и строка2 должны совпадать.

[2 addr ] ! функция

Применить функцию (или список команд, если для аргумента функция указано значение ) только к строкам, не выбранным посредством адресов.

[0 addr ] : метка

Эта команда не выполняет никаких действий; она определяет значение аргумента метка для команд b и t , к которым требуется перейти.

Поместить текущий номер строки в стандартный поток вывода в виде строки с собственным номером.

Пустая команда; игнорируется.

В файле myfile найти и вывести только те строки, которые содержат строку " tom ":

sed -n -e "/tom/p" myfile

В файле myfile заменить все вхождения строки beneath строкой below и вывести в файл newfile :

sed -e "s/beneath/below/" myfile >newfile

Все файлы являются текстовыми. Файлы_сценариев , имена которым присвоены с помощью опции -f , состоят из команд правки (по одной в каждой строке). С помощью команды r можно указать любое число дополнительных текстовых входных файлов для вставки неотредактированных данных в стандартный поток вывода в точках, предварительно определенных по правилам правки. С помощью команды w в сценарии можно указать до 10 дополнительных выходных файлов.

Если не удается открыть для чтения один или несколько входных файлов (к ним не относятся файлы сценариев), утилита sed продолжает обработку остальных файлов.

Предостережение

Замечание

(drBatty) Что касается самой первой строки, то я там ставлю sha-bang после чего, я могу запускать свои скрипты, как обычные команды (./my_sed_script во время отладки, а перенеся их в /usr/local/bin/, просто набрав my_sed_script). Оболочка сама определяет, что это sed-скрипт и выполняет его. Таким скриптом можно пользоваться как и обычной sed, например:
  1. я вывожу в stdout входной файл(input.txt), он обрабатывается моим скриптом, и записывается в output.txt
  2. тоже самое, что и в п1, просто тут сам скрипт читает файлы
  3. Редактирование "на месте", отредактированный файл записывается ВМЕСТО test.txt, при этом, старый файл сохраняется под именем "test.txt.bak".
  4. В данном случае, оболочка выдаёт моему скрипту все html файлы, которые скрипт последовательно обрабатывает(каждый отдельно, см. описание -i выше). При этом, старые файлы сохраняются в каталоге backu_dir(если он есть и доступен).

q [EXIT-CODE]

Эта команда принимает только один адрес.

Прерывание работы скрипта. Если не запрещён автоматический вывод буфера (без опции -n), буфер выводится в выходной поток. Можно дополнительно задать код завершения ( EXIT-CODE ). (это GNU расширение).

d

Удаляет содержимое буфера; после чего переходит к следующему циклу.

Замечание

(drBatty): таким образом, эта команда примерно эквивалентна но при этом, ничего не выводится, все команды после d не выполняются. (потому сложно сказать, действительно-ли очищается буфер) конечно "sed '5d'" действительно отфильтрует пятую строку, но при этом, следует помнить, что не всё так просто. См. также.

p

Печать буфера (в stdout). Эту команду имеет смысл использовать только при использовании опции -n.

Замечание

в моей версии sed применение этой команды без опции -n приводит к дублированию строк, в оригинале написано, что другие версии могут печатать только один раз, а стандарт POSIX трактует это как ошибку.

Потому в переносимых скриптах НЕ СЛЕДУЕТ использовать команду p без ключа -n (это касается так-же модификатора p команды s).

Подсказка

(drBatty): что-же делать, если надо вывести строку 2 раза? ИМХО необходимо использовать опцию -n, и в случае дублирования дублировать команду p. Примитивный пример:

n

Если авто-печать не отключена, печатает буфер, и затем заменяет содержимое буфера на следующую строку. Если авто-печать отключена (опция -n), то просто меняет содержимое буфера на следующую строку. Если следующей строки нет(текущая - последняя в тексте), то эта команда просто выводит содержимое буфера (если это разрешено), и работа скрипта завершается(следующие за n команды НЕ выполняются).

Группировка команд в блок. Вы можете использовать такие блоки, если хотите, что-бы некоторые команды выполнялись только для некоторых адресов(или диапазонов). Пример:

эта команда будет просто печатать все строки, так-как 3p игнорируется для всех строк, однако, для третей строки команда 3p выполнится. (третья будет распечатана 2 раза).

Ничего не распечатает, кроме третьей строки, которая выведется дважды.

Замечание

Вообще-то говоря, < является командой , и это нужно учитывать.

s

Команда 's' является самой востребованной в sed-скриптах, это команда замены. Точнее будет сказать, это команда поиска, и(если найдено) замены. Синтаксис команды:

Символ '/' разделяет части команды. Его можно поменять на любой другой символ. Если в РЕГУЛЯРНОМ_ВЫРАЖЕНИИ или в ВЫРАЖЕНИИ_ДЛЯ_ЗАМЕНЫ требуется использовать символ-разделитель('/' обычно), то его следует за экранировать.

Базовая концепция 's' проста: она ищет РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ , и, если его найдёт, заменяет найденное на ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ .

ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ может содержать `\N' (где N - цифра 1. 9), эта "обратная ссылка" заменяется на подвыражение (в скобках) из РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ . Выражения нумеруются слева-направо. Если ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ содержит '&', то он заменяется на всю найденную строку.

Замечание

(drBatty): аналогично '&' работает '\0'. По этой причине, в ВЫРАЖЕНИЕ_ДЛЯ_ЗАМЕНЫ (впрочем и в РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ ) невозможно использовать октальные символы в Си-стиле (вроде \033). Они воспринимаются как обратные ссылки на всю строку. Для использования символов с восьмеричным кодом вы можете использовать конструкцию \oQQQ, где QQQ - восьмеричные цифры. \L Заменяет БОЛЬШИЕ буквы на маленькие. Действует до \U или до \E \l Заменяет один следующий символ на мАЛЕНЬКИЙ. \U Заменяет все следующие символы на БОЛЬШИЕ, действует до \L или до \E . \u Заменяет один сл. символ на Большой \E Остановка замены регистров начатых префиксами \L и \U .

Замечание

Для команды s предусмотрено множество МОДИФИКАТОРОВ :

g Производится замена всех найденных вхождений РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ . (по умолчанию - только первое вхождение заменяется). НОМЕР Заменяется только заданное НОМЕР ом найденное вхождение РЕГУЛЯРНОГО_ВЫРАЖЕНИЯ .

Замечание

Примечание: POSIX стандарт не описывает ситуацию комбинирования МОДИФИКАТОРОВ g и НОМЕР , GNU версия sed обрабатывает такую комбинацию сл. образом: Игнорируются все совпадения до совпадения НОМЕР , а начиная с совпадения НОМЕР все заменяются. Думаю нужны примеры в данном случае: p Если РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ найдено, то происходит вывод буфера в выходной поток.

Замечание

Если вы используете сразу два МОДИФИКАТОРА p и e , то от их порядка зависит результат. Например:

Замечание

В данном примере используется неверное применение замены модификатора pep (который не поддерживается). Более правильным будет использование команды T после команды s///pe .

Другие команды(y,a,i,c,=,l,r,w,D,N,P,h,H,g,G,x).

Многие sed-скрипты используют только команду s , описанную в прошлой секции, однако, не стоит забывать, что sed умеет намного больше простой замены. Вот список часто используемых команд sed :

y / ЗАМЕНЯЕМЫЕ_СИМВОЛЫ / ЗАМЕНЯЮЩИЕ_СИМВОЛЫ /

Эта команда заменяет символы из списка ЗАМЕНЯЕМЫЕ_СИМВОЛЫ , на символы из списка ЗАМЕНЯЮЩИЕ_СИМВОЛЫ . Списки должны быть одинаковой длинны (после де-экранирования).

Замечание

Внимание

Глюки и баги могут возникнуть и сами по себе, к примеру так.

a TEXT

Это расширение так-же работает и в командах i и c .

i TEXT Так-же как a , но TEXT выводится перед выводом буфера. c TEXT Так-же как a , но TEXT выводится вместо выводам буфера. = Так-же как i , но выводится не заданный текст, а номер текущей строки. Пример: l [ N ]

N определяет максимальный размер строки, если не задан, принимается значение заданное в командной строке ключом -l , если и он не задан, N =70. Если N =0, строки не разбиваются. Параметр N - расширение GNU.

r FILENAME

w FILENAME

Записывает буфер в FILENAME . См. так-же описание модификатора w команды s .

D

Это совсем мутная команда, здесь кардинальным образом нарушается вся работа sed:

  1. читаем строку из входного файла в буфер.
  2. выполняем скрипт до команды D .
  3. Выполняем команду D :

Таким образом, можно напихать в буфер множество строк, а после этого все это строки обработать по одной. Весь скрипт получается таким своеобразным циклом, который не слишком и удобен, по той причине, что точка входа в цикл всего одна, и совпадает с началом скрипта. Конечно, хотя точка входа единственная, точек выхода сколько угодно, и конечно эту команду всегда можно обойти.

Замечание

N

Добавляет новую строку из входного потока к буферу. Строки разделяются символом новой строки(\n). Если нет следующей строки, то работа sed завершается без выполнения оставшихся команд. Команда довольно мутная, поясню примером с прошлым файлом из двух строк:

P

Печать буфера сначала, и до первого символа \n.

h

Запись буфера в буфер2 (hold space).

H

Добавление буфера к буферу2. Например:

g

Замена содержимого буфера, на содержимое буфера2.

G

Добавляет к буферу содержимое буфера2. (вроде H, только меняется буфер).

x Обмен содержимым буфера и буфера2

Замечание

Ещё одно примечание: для работы с буфером2 (областью удержания) есть довольно много команд, если вам нужно просто копирование - предпочтительнее использовать x , она в некоторых случаях должна работать быстрее (а фиг там! В текущей версии sed(4.2) это не так, см здесь), иначе используйте g и h . Команды G и H отличаются результатом: например если в буфере будет "АБВ", а в буфере2 будет "ГДЕ", и мы выполним G , то результат в буфере будет "АБВ\nГДЕ", а вот если мы выполним команду H , то не только результат поместится в область удержания, но и поменяется, получится "ГДЕ\nАБВ".

Команды для sed гуру(:,b,t).

Во многих случаях, используя следующие команды, вы можете избежать кодинга на других языках (вроде perl & awk ), и решить задачи средствами самой sed .

Замечание

ага. Чтоб мну не обвиняли в подтасовке фактов процитирую оригинал:
In most cases, use of these commands indicates that you are probably better off programming in something like `awk' or Perl. But occasionally one is committed to sticking with `sed', and these commands can enable one to write quite convoluted scripts.
: LABEL Безадресная команда. Она задаёт метку, для перехода командами t , T , и b . b [LABEL] Безусловный переход на метку LABEL . Если LABEL не применяется, то завершает этот цикл, и начинает следующий. t [ LABEL ] Переход по метке LABEL . В том случае, если последняя команда s успешно завершилась (произвела замену). При этом, если LABEL опущена, команда прерывает цикл, и начинает следующий. Если прошлая команда s не произвела замены, команда ничего не делает.

Подсказка

условный переход в sed вовсе не обязательно делать с помощью `t'! Вы можете с лёгкостью использовать команду `b' с адресом. Например переход на lable в команде осуществляется тогда, и только тогда, когда в буфере есть хотя-бы одна буква X. Многоуровневые, вложенные и обратные (в т.ч. циклы) переходы тоже работают.

Предостережение

Замечание

Поковыряв исходники, я выяснил, что команда s только устанавливает флаг перехода (и то не всегда, а только тогда, когда произошла замена), но команда s никогда не сбрасывает флаг перехода. Он сбрасывается только командами t и T . Кроме того, флаг перехода сбрасывается во время загрузки строки в буфер в начале цикла работы sed. Если вы загружаете строки командами n и/или N , то флаг перехода не сбрасывается. Потому и приходится применять такой код:

Замечание

Команды специфичные для GNU `sed'(e,L,Q,R,T,v,W)

Эти команды специфичны для GNU версии sed, вы можете использовать их в том, и только в том случае, если вы уверены, что ваши скрипты не понадобится запускать на других версиях sed.

Замечание

(drBatty): Наверное имеется ввиду версия sed от NecroSoft, которая не поддерживает половину команд, и стОит всего $49.50 :-) e [ COMMAND ] Эта команда вызывает по конвейеру (pipe) оболочку sh , которая выполняет команду COMMAND . Если COMMAND отсутствует, выполняется команды из входного потока. (см. так-же команду s , модификатор e ). L N Это расширение разбивает длинную строку на короткие. Строка разделяется по пробельным символам. Насколько строка "длинная" определяется параметром N (либо ключом -l, если N отсутствует). Работает примерно как команда fmt. См. так-же описание команды l. Q [ EXIT-CODE ] Эта команда может иметь только один адрес. Работает так-же как q , но не выводит содержимое буфера в конце цикла. В оригинале написано, что эта команда представляет собой альтернативный путь, что-бы не использовать ключ -n в тривиальных функциях. R FILENAME Так-же как r , но читается только одна строка из файла FILENAME . Например: выведет сначала первую строку файла2, потом первую строку файла1, затем вторую файла2 и т.д. Т.о. эта команда выведет оба файла, второй в нечётных, а первый в чётных строках результата. T [ LABEL ] так-же как t , но переход выполняется в случае неудачной замены команды s . v VERSION Эта команда ничего не делает, если версия sed моложе или такая-же как VERSION . В противном случае скрипт прерывается с ошибкой. Вот более современная версия:

Подсказка

Подсказка

Конечно file1 можно как-нибудь отредактировать этой командой в процессе записи. Разница между командами w и W следующая: первая выводит буфер в файл, и закрывает последний, а вторая не закрывает - файл закрывается только после обработки всего входного потока.

Команда z

Замечание

(drBatty): В новейших версиях GNU sed появилась новая команда z, она очищает буфер. Однако, пока ещё в большинстве систем эта версия не установлена, и очищать приходится командой s/.*// , что во первых не работает если в буфере есть НЕСИМВОЛЫ, и во вторых теряется флаг для команд перехода.

Подробнее про эту команду см. здесь. И здесь.

Вы можете обсудить этот документ на форуме. Текст предоставляется по лицензии GNU Free Documentation License (Перевод лицензии GFDL).

Вы можете пожертвовать небольшую сумму яндекс-денег на счёт 41001666004238 для оплаты хостинга, интернета, и прочего. Это конечно добровольно, однако это намного улучшит данный документ (у меня будет больше времени для его улучшения). На самом деле, проект часто находится на грани закрытия, ибо никаких денег никогда не приносил, и приносить не будет. Вы можете мне помочь. Спасибо.

Команда sed в Linux

Сначала рассмотрим синтаксис команды:

$ sedопции-e командыфайл

А вот её основные опции:

Установка

Здесь не нужно много рассказывать. Скорее все sed у вас уже установлен, так как он используется различными системными скриптами, а также пользователями Linux, которые хотят повысить эффективность своей работы. Вы можете узнать, какая версия sed у вас установлена, с помощью команды:

Концепции

Как работает sed

Теперь нужно понять как работает команда sed. У утилиты есть два буфера, это активный буфер шаблона и дополнительный буфер. Оба изначально пусты. Программа выполняет заданные условия для каждой строки в переданном ей файле.

sed читает одну строку, удаляет из неё все завершающие символы и символы новой строки и помещает её в буфер шаблона. Затем выполняются переданные в параметрах команды, с каждой командой может быть связан адрес, это своего рода условие и команда выполняется только если подходит условие.

Когда всё команды будут выполнены и не указана опция -n, содержимое буфера шаблона выводится в стандартный поток вывода перед этим добавляется обратно символ перевода строки. если он был удален. Затем запускается новая итерация цикла для следующей строки.

Если не используются специальные команды, например, D, то после завершения одной итерации цикла содержимое буфера шаблона удаляется. Однако содержимое предыдущей строки хранится в дополнительном буфере и его можно использовать.

Адреса sed

Каждой команде можно передать адрес, который будет указывать на строки, для которых она будет выполнена:

Если для команды не был задан адрес, то она будет выполнена для всех строк. Если передан один адрес, команда будет выполнена только для строки по этому адресу. Также можно передать диапазон адресов. Тогда адреса разделяются запятой и команда будет выполнена для всех адресов диапазона.

Синтаксис

Синтаксис данной утилиты не отличается сложностью. Он представлен в виде:

Первоначально необходимо изучить основные параметры, которые поддерживает команда:

sed -e [команды] (файл)

Первоначально кажется, что данная утилита очень сложная. На самом деле это не так, ей сможет пользоваться даже новичок в сфере программирования.

Стоит отметить, что данная утилита имеет два отдельно обособленных буфера – это основной и вспомогательный буфер (активного и пассивного плана). Первоначально они абсолютно пусты. Специальная программа передает предварительно определенные условия для всех строк передаваемого файла.

Первоначально программа «sed» изучает одну строку. Из нее удаляются все завершающие данные, а также символы, присутствующие в новой строке. Обрабатываемая стока помещается в главный буфер.

Далее выполняются команды, которые были переданы пользователем в параметрах. За каждой определенной командой закрепляется адрес. Он используется в качестве своеобразного условия. Команда пройдет лишь в том случае, если данное условие будет соблюдено.

После выполнения всех предписанных команд, содержимое буфера шаблона попадает в классический поток вывода. Это происходит в том случае, если предварительно не была указана функция «-n», которая ограничивает вывод содержимого.

Когда символ перевода изначально был удален, он добавляется обратно. Только после этого запускается следующая интерпретация, подразумевающая обработку новой строки.

Когда пользователь не планирует использование специальных команд, после завершения первой интерпретации все содержимое основного буфера будет удалено. Стоит отметить, что содержимое, которое относится к первоначально обработанной строке, сохраняется во вспомогательном буфере. Его применяют в дальнейшем при осуществлении задач.

Особенности адресов, предающихся утилите «sed»

Все команды получают свой адрес. Именно он указывает на строки, для которых выполняется команда:

  • «номер». В данном случае прописывается номер определенной строки, где в последующем будет выполняться команда.
  • «первая

Когда пользователь не желает задавать определенный адрес для программы «sed», она распространяется на все строки в файле. Если передается один адрес, команда выполняется до той строки, которая расположена по указанному адресу.

Есть возможность передавать диапазон адресов. Информация разделяется запятыми, а команда осуществляется для тех адресов, которые находятся в требуемом диапазоне.

Использование специальных символов:

Полный набор не ограничен только этими тремя. Sed прекрасно понимает регулярные выражения (regular expressions).

Следующая команда заменит root на Admin в тех строках, которые начинаются с user:

Следующая команда заменит root на Admin в тех строках, которые заканчиваются словом data:

С помощью следующей конструкции слово root с пробелом после него будет заменено на Admin с двоеточием:

В случае использования символа (pipe) в качестве разделителя спецсимволы экранировать не нужно, но при этом регулярные выражения работать не будут

Регулярные выражения

Убрать все цыфры из вывода:

Продублировать отсеченное значение:

Регулярное выражение 8* определят 0 или больше цыфр.
Регулярное выражение 68* определят 1 или больше цыфр.

Пробел в левой части выражения может быть заменен на любой другой разделитель.

Замена текства между двумя словами:

Использование переменных в выражениях sed

При написании bash скриптов мы используем переменные. Иногда возникает необходимость использовать эти переменные в выражениях sed.

Основные команды Sed

Для того чтобы применить SED достаточно ввести в командную строку

echo ice | sed s/ice/fire/

Замена слова в файле

Обычно SED применяют к файлам, например к логам или конфигам.
Предположим, что у нас есть файл input.txt следующего содержания

Here is a StringHere is an IntegerHere is a Float

Мы хотим заменить слово Here на There

Результат будет выведен в консоль:

There is a String
There is an Integer
There is a Float

В этом случае перепишется исходный файл input.txt

Рассмотрим пример посложнее. Файл input.txt теперь выглядит так:

Here is an Apple. Here is a Pen. Here is an ApplePenInteger is HereHere is a FloatHere is a Pen. Here is a Pineapple. Here is a PineapplePen

Как Вы сейчас увидите, замена произойдёт только по одному разу в строке

There is an Apple. Here is a Pen. Here is an ApplePen
Integer is There
There is a Float
There is a Pen. Here is a Pineapple. Here is a PineapplePen

Чтобы заменить все слова нужна опция g

There is an Apple. There is a Pen. There is an ApplePen
Integer is There
There is a Float
There is a Pen. There is a Pineapple. There is a PineapplePen

Замена слова в файле и вывод результата в другой файл

Та же замена, но с выводом в новый текстовый файл, который мы назовём output:

Замена слова в нескольких файлах одновременно

Если нужно обработать сразу несколько файлов: например файл 1.txt с содержанием

First File: Here

И файл 2.txt с содержанием

Second File: Here

Это можно сделать используя *.txt

На выходе файл output.txt будет выглядеть так

First File: ThereSecond File: There

Отбросить всё, что левее определённого слова

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String it has a NameHere is an Integer it has a NameHere is a Float it has a Name

Мы хотим отбросить всё, что находится левее слова it, включая слово it, и записать в файл.

^ означает, что мы стартуем с начала строки Результат:

has a Name
has a Name
has a Name

Для доступности объясню синтаксис сравнив две команды. Посмотрите внимательно, когда мы заменяем слово Here на There.
There находится между двумя слэшами. Раскрашу их для наглядности в зелёный и красный.

А когда мы хотим удалить что-то, мы сначала описываем, что мы хотим удалить. Например, всё от начала строки до слова it.
Теперь в правой части условия, где раньше была величина на замену, мы ничего не пишем, т.е. заменяем на пустое место. Надеюсь, логика понятна.

Отбросить всё, что правее определённого слова

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String / it has a NameHere is an Integer / it has a NameHere is a Float / it has a Name

Мы хотим отбросить всё, что находится правее слова is, включая слово is, и записать в файл.

Экранирование символов в sed

Специальные символы экранируются с помощью
Предположим, что у нас есть файл input.txt следующего содержания

Here is a String / it has a NameHere is an Integer / it has a NameHere is a Float it / has a Name

Мы хотим отбросить всё, что находится левее /a, включая /a, и записать в файл.

В результате получим ошибку

Чтобы команда заработала нужно добавить перед /

Here is a StringHere is an IntegerHere is a Float

Два условия одновременно в Sed

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String /b it has a NameHere is an Integer /b it has a NameHere is a Float /b it has a Name

Удаление переходов на новую строку

Удалить всё после определённой строки

Допустим Вы хотите удалить все строки после третьей

sed 3q input.txt > output.txt

Удаление текста

Можно легко удалить текст, который мы выводили в предыдущем примере, заменив команду “p” на команду “d”. Команда «-n» нам больше не нужна, потому что при использовании команды удаления утилита выводит все, что не удалено. Это позволяет нам видеть, что происходит. Изменим последнюю команду из предыдущего раздела так, чтобы она удаляла все нечетные строки, начиная с первой. В результате мы должны получить все строки, которые не были выведены в прошлый раз.

Открыв этот файл командой cat, мы увидим тот же результат, который был на экране после выполнения предыдущей команды. По умолчанию sed не редактирует исходный файл в целях безопасности. Это можно изменить при помощи опции «-i», которая означает редактирование на месте. Исходный файл будет изменен. Давайте попробуем отредактировать только что созданный нами файл «everyother.txt». Снова удалим все нечетные строки:

При помощи cat можно убедиться, что файл был отредактирован.

Опция “-i” может быть опасной, но утилита предоставляет возможность создания резервной копии перед редактированием. Для этого сразу после опции “-i” укажите расширение резервной копии “.bak”:

Будет создан файл резервной копии с расширением “bak”, а затем выполнено редактирование исходного файла.

Замена текста

Чаще всего sed используется для замены текста. Редактор позволяет осуществлять поиск текста по шаблону при помощи регулярных выражений. А затем заменять найденный текст. В простейшем варианте можно заменить одно слово на другое, используя следующий синтаксис:

Параметр «s» – это команда замены. Три слэша (/) нужны для разделения различных текстовых полей. Если вам удобно, вы можете использовать для этого другие символы. Например, если нам нужно изменить имя веб-сайта, удобнее использовать другой разделитель, так как URL содержат слэши. Воспользуемся командой echo для передачи примера:

Здесь секция «com/index» заменяется на «org/home». В качестве разделителя используется нижнее подчеркивание «_». Не забудьте про последний разделитель, иначе sed выдаст ошибку.

Создадим файл для отработки замен:

Теперь заменим «on» на «forward»

Стоит обратить внимание на ряд моментов. Во-первых, мы заменяем шаблоны, а не слова. “on” в слове “song” было заменено на “forward”. Во-вторых, второе “on” в строке 2 заменено не было. Это произошло потому, что по умолчанию команда “s” обрабатывает первое совпадение в строке. А затем переходит к следующей строке. Для замены каждого “on”, а не только первого в строке, можно указать команде замены флаг “g” после шаблонов:

Теперь были заменены все “on”. Чтобы заменить только вторые “on” в каждой строке, вместо “g” нужно указать “2”:

Если нам нужно вывести только те строки, где выполнялась замена, для отмены автоматического вывода можно снова воспользоваться опцией «-n». Затем мы можем передать флаг “p” для вывода строк, в которых производились замены.

Пример показывает, что флаги в конце команды можно комбинировать. Чтобы игнорировать регистр, нужно указать флаг “i”.

Если нужно заменить текст во всех файлах директории то можно воспользоваться командой

Примеры использования sed

В окружении UNIX: конвертируем новые строки DOS (CR/LF) в формат Unix.

Предполагаем, что все строки оканчиваются на CR/LF

В bash/tcsh, нажмите Ctrl-V затем Ctrl-M

Работает на ssed, gsed 3.02.80 или выше

В окружении UNIX: конвертируем новые строки Unix (LF) в формат DOS.

Командная строка под ksh

Командная строка под bash

Командная строка под zsh

gsed 3.02.80 или выше

В окружении DOS: конвертируем новые строки Unix (LF) в формат DOS.

В окружении DOS: конвертировать DOS переводы строк (CR/LF) в формат Unix.

Может быть только сделано с UnxUtils sed, версии 4.0.7 или выше. Версию UnxUtils можно узнать пользовательским свичем “–text”, который появляется когда вы используете свич “–help”. В других случаях изменение перевода строк DOS в перевод строк Unix не может быть выполнено в окружении DOS. Используйте вместо этого “tr”.

UnxUtils sed v4.0.7 или выше

GNU tr версия 1.22 или выше

Удалить пустоту в начале (пробелы, табуляции) от передней части каждой строки выравнивает весь текст по левому краю

Удаление пустоты (пробелы, табуляции) в конце каждой строки

Удаление пустоты как в начале, так и в конце каждой строки

Вставка 5 пробелов в начале каждой строки (сделать отступ страницы)

Выравнять весь текст заподлицо справа на 79-ом столбце по ширине

Центрировать весь текст в середине на 79-ом столбце по ширине

В первом методе пробелы в начале строки имеют значение, и в конце строки добавляются пробелы.

Во втором методе пробелы из начала строки отбрасываются в центрируемой строке, и в конце строки пробелы не добавляются.

Подстановка (поиск и замена “foo” на “bar” в каждой строке

Заменить только первое вхождение в строке

Заменить только четвёртое вхождение в строке

Заменить ВСЕ вхождения в строке

Заменяет следующее-на-последнее вхождение (the next-to-last case)

Поменять только последний случай

Поменять “foo” на “bar” ТОЛЬКО для строк, которые содержат “baz”

Заменить “foo” на “bar” КРОМЕ строк, которые содержат “baz”

Поменять “scarlet” или “ruby” или “puce” на “red”

Обратный порядок строк (эмулирует “tac”) баг/фича в HHsed v1.5 приводит к тому, что пустые строки удаляются

Обратный порядок всех символов в строке (эмулирует “rev”)

Соединить пары строк (наподобие “paste”)

Если строка заканчивается на обратный слэш, прикрепить к ней следующую строку

Если строка начинается со знака равно, прикрепить её к предыдущей строке и заменить “=” на пробел

Добавить запятые в цифровую строку, замена “1234567” на “1,234,567”

Добавить запятые к номерам, в том числе содержащим десятичные точки и знаки минус (GNU sed)

Добавить пустую строку каждые 5 строк (после каждых 5, 10, 15, 20 и т. д. строк)

Выборочная печать конкретных строк:

Напечатать первые 10 строк файла (эмулирует поведение “head”)

Напечатать первую строку файла (эмулирует “head -1″)

Напечатать последние 10 строк файла (эмулирует “tail”)

Напечатать последние 2 строки файла (эмулирует “tail -2″)

Напечатать последнюю строку файла (эмулирует “tail -1″)

Напечатать строки файла начиная с последней

Для файла в одну строку напечатать пустую строку

Для файла в одну строку, напечатать эту строку:

Для файла в одну строку ничего не печатать

Печатать только строки, которые соответствуют регулярному выражению (эмулирует “grep”)

Печатать только строки, которые НЕ соответствуют регулярному выражению (эмулирует “grep -v”)

Метод 1, соответствует вышеприведённому

Метод 2, упрощённый синтаксис

Печатать строку, которая идёт перед строкой, удовлетворяющей регулярному выражению, но не строку, содержащую регулярное выражение

Печатать строку, которая идёт сразу после регулярного выражения, но не строку, содержащую регулярное выражение

Печатать по одной строке перед и после регулярного выражения, с номером строки, показывающей где встретилось регулярное выражение (наподобии “grep -A1 -B1″)

grep для AAA и BBB и CCC (в любом порядке)

grep для AAA и BBB и CCC (в таком порядке)

grep для AAA или BBB или CCC (эмулирует “egrep”)

Напечатать параграф, если он содержит AAA (параграфы разделяют пустые строки) HHsed v1.5 должен вставить ‘G;’ после ‘x;’ в следующих трёх скриптах ниже

Напечатать параграф, если он содержит AAA и BBB и CCC (в любом порядке)

Напечатать параграф, если он содержит AAA или BBB или CCC

Напечатать только строки длинной 65 символов или длиннее

Напечатать только строки, которые короче 65 символов

Метод 1, соответствует вышеприведённому

Метод 2, упрощённый синтаксис

Напечатать секцию файла от регулярного выражения до конца файла

Напечатать строку с номером 52

Способ 3, эффективен на больших файлах

Начиная со строки 3, печатать каждую седьмую строку

Напечатать раздел файла между двумя регулярными выражениями (включая)

Выборочное удаление конкретных строк:

Напечатать весь файл КРОМЕ секции между двумя регулярными выражениями 2

Удалить дубликаты последовательных строк файла (эмулирует “uniq”). Первая строка из двух дублирующих сохраняется, остальное удаляется.

Удалить дубликаты непоследовательных строк из файла. Остерегайтесь переполнения буфера или используйте GNU sed.

Удалить все строки, кроме дублирующих строк (эмулирует “uniq -d”).

Удалить первые 10 строк файла

Удалить последние строки файла

Удалить последние 2 строки файла

Удалить последние 10 строк файла

Удалить каждую восьмую строку файла

Удалить строки, содержащие паттерн

Удалить ВСЕ пустые строки из файла (то же самое что и “grep ‘.’ “)

Удалить все ПОСЛЕДОВАТЕЛЬНЫЕ пустые строки из файла, кроме первой, также удаляет все пустые строки в начале и в конце файла (эмулирует “cat -s”)

Способ 1, позволяет 0 пустых строк вверху, 1 в EOF

Способ 2, позволяет 1 пустую строку вверху, 0 в EOF

Удалить все ПОСЛЕДОВАТЕЛЬНЫЕ пустые строки из файла кроме первых двух:

Удалить все первые пустые строки в файле

Удалить все конечные пустые строки в файле

Удалить последнюю строку каждого параграфа

Заключение

Мы рассмотрели основы использования sed. Теперь вы можете быстро редактировать текстовые документы при помощи соответствующих команд sed.

20 примеров использования потокового текстового редактора sed

Команда sed (потоковый редактор) это очень мощная утилита работающая в Linux/Unix системах. В основном он используется для поиска и замены текста , но так же может применяться и для других манипуляций, таких как вставка, удаление, поиск и т.п. С sed, вы можете отредактировать файл не выполняя полного его открытия. В sed так же поддерживаются регулярные выражения, которые превращают sed в мощное средство манипуляцией текста.

В этой статье приведу несколько примеров использования SED. Основной синтаксис использования sed:

Картинка 1
1. Отобразить часть файла

С помощью sed мы можем просмотреть не весь файл, а только его часть. Посмотреть нужные строки можно так:

Опция n указывает что требуется вывести часть файла, а опция p, что требуется вывести только строки с 22 по 29.

2. Отобразить все кроме указанных строк.

Опция d указывает что надо удалить из вывода строки с 22 по 29.

3. Вывод каждой N строки начиная M строки .

Теперь, например выведем каждую 3-ю строку начиная со строки 2-ой.

4. Удаление строки из файла используя sed.

Где N это номер строки а опция d указывает что надо удалить эту строку. Чтобы удалить самую последнюю строку в файле выполните команду:

5. Удаление диапазона строк.

Данная команда удалит строки с 29 по 34 из файла testfile.txt

6. Удаление всех строк кроме указанных.

7. Вставка пустой строки/пробелов.

8. Поиск и замена строки.

Для поиска и замены найденной строки в файле:

В этом примере мы ищем слово danger и сразу меняем его на слово safety в каждой строке, но только в первом найденном вхождении.

9. Поиск и замена ВСЕХ найденных в файле слов.

10. Заменить n-ое вхождение шаблона строки.

Мы также можем заменить строку при n-ом найденном. Например заменим «danger» на «safety» только на второе появление в поиске:

Для замены «danger» на «safety» во втором найденном результате в КАЖДОЙ строке файла:

11. Заменить текст на определенной строке.

Здесь мы явно указали что надо на 4 строке в файле testfile.txt заменить первое найденное слово danger на слово safety. Так же мы можем указать диапазон строк для поиска и последующей замены:

12. Добавить строку до/после совпадения с заданным поиском.

13.Замена всей строки при совпадении поиска.

14. Запуск нескольких команд sed.

15. Создание резервной копии перед изменением файла.

Этак команда выполнит редактирование файла, но перед этим создаст его копию с расширением .bak. Вы можете, конечно же, использовать любое другое расширение.

16. Удаление текста начиная с указанного слова и заканчивая другим словом.

Чтобы удалить строку файла, начинающуюся с определенного слова и заканчивая другим словом выполните:

17. Добавление строк.

Чтобы добавить контент перед каждой строкой с помощью sed & regex, используйте команду:

18. Удаление всех комментариев и пустых строк.

Для удаления только комментариев:

19. Получение списка пользователей из файла /etc/passwd.

Данная команда выведет на экран список пользовательских имён.

20. Запрет перезаписи системных ссылок с помощью команды sed.

К примеру мы захотели отключить SELinux на сервере с CentOS или RHEL:

Читайте также: