Sed linux заменить маленькие символы на большие

Обновлено: 06.07.2024

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

Замечание

(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 - это потоковый редактор текста, работающий по принципу замены. Его можно использовать для поиска, вставки, замены и удаления фрагментов в файле. С помощью этой утилиты вы можете редактировать файлы не открывая их. Будет намного быстрее если вы напишите что и на что надо заменить, чем вы будете открывать редактор vi, искать нужную строку и вручную всё заменять.

В этой статье мы рассмотрим основы использования команды sed linux, её синтаксис, а также синтаксис регулярных выражений, который используется непосредственно для поиска и замены в файлах.

Команда sed в Linux

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

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

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

  • -n, --quiet - не выводить содержимое буфера шаблона в конце каждой итерации;
  • -e - команды, которые надо выполнить для редактирования;
  • -f - прочитать команды редактирования из файла;
  • -i - сделать резервную копию файла перед редактированием;
  • -l - указать свою длину строки;
  • -r - включить поддержку расширенного синтаксиса регулярных выражений;
  • -s - если передано несколько файлов, рассматривать их как отдельные потоки, а не как один длинный.

Я понимаю, что сейчас всё очень сложно, но к концу статьи всё прояснится.

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

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

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

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

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

2. Адреса sed

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

  • номер - позволяет указать номер строки, в которой надо выполнять команду;
  • первая

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

3. Синтаксис регулярных выражений

Вы можете использовать такие же регулярные выражения, как и для Bash и популярных языков программирования. Вот основные операторы, которые поддерживают регулярные выражения sed Linux:

  • * - любой символ, любое количество;
  • \+ - как звездочка, только один символ или больше;
  • \? - нет или один символ;
  • \ - любой символ в количестве i;
  • \ - любой символ в количестве от i до j;
  • \ - любой символ в количестве от i и больше.

4. Команды sed

Если вы хотите пользоваться sed, вам нужно знать команды редактирования. Рассмотрим самые часто применяемые из них:

Утилите можно передать несколько команд, для этого их надо разделить точкой с запятой или использовать две опции -e. Теперь вы знаете всё необходимое и можно переходить к примерам.

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

Теперь рассмотрим примеры sed Linux, чтобы у вас сложилась целостная картина об этой утилите. Давайте сначала выведем из файла строки с пятой по десятую. Для этого воспользуемся командой -p. Мы используем опцию -n чтобы не выводить содержимое буфера шаблона на каждой итерации, а выводим только то, что нам надо. Если команда одна, то опцию -e можно опустить и писать без неё:

sed -n '5,10p' /etc/group

Или можно вывести весь файл, кроме строк с первой по двадцатую:

sed '1,20d' /etc/group

Здесь наоборот, опцию -n не указываем, чтобы выводилось всё, а с помощью команды d очищаем ненужное. Дальше рассмотрим замену в sed. Это самая частая функция, которая применяется вместе с этой утилитой. Заменим вхождения слова root на losst в том же файле и выведем всё в стандартный вывод:

sed 's/root/losst/g' /etc/group

Флаг g заменяет все вхождения, также можно использовать флаг i, чтобы сделать регулярное выражение sed не зависимым от регистра. Для команд можно задавать адреса. Например, давайте выполним замену 0 на 1000, но только в строках с первой по десятую:

sed '1,10 s/0/1000/g' /etc/group

Переходим ещё ближе к регулярным выражениям, удалим все пустые строки или строки с комментариями из конфига Apache:

sed 's/[$p*]/losst_p/g' /etc/group

Если вам надо записать результат замены в обратно в файл можно использовать стандартный оператор перенаправления вывода > или утилиту tee. Например:

Также можно использовать опцию -i, тогда утилита не будет выполнять изменения в переданном ей файле:

Если надо сохранить оригинальный файл, достаточно передать опции -i в параметре расширение для файла резервной копии.

Выводы

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

Нет похожих записей


Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна.

Оцените статью:

(14 оценок, среднее: 2,64 из 5)

Об авторе

11 комментариев

Да. Было время, когда и я тоже пользовался sed-ом. Причём несколько раз.
Но потом понял -- мне проще и быстрее выполнять редактирование текста в обычном редакторе.

Если работа происходит в графической консоли (у меня Debian, MATE), то проще запустить текстовый редактор pluma. Если же нужно выполнить редактирование удалённого файла (в смысле на другом компе), то это проще сделать с помощью nano или mcedit (из пакета mc). На крайняк скопировать удалённый файл к себе на комп, изменить и вернуть обратно. Но использовать sed-ом -- 🙁 . смысл этого я что-то не очень понимаю. На минутчку! За последние лет 10 я его так ни разу по делу и не использовал, не было нужды прибегать именно к нему на фоне других редакторов текста.

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

Да, sed -- очень симпатичный и быстрый редактор. Я искренне извиняюсь, но я просто не вижу ему реальных применение. Разве что понастальгировать. Но это из области эмоций, а не технологий. Мир Линукса изменился сильно со времен, когда sed был актуален. Изменились инструменты. Изменился подход к решению задач.

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

Спасибо!
Несколько далёк от этой области. Тоже программер, но пишу под микроконтроллеры и немного для компов (десктоп-программулины). Админка и вэб -- не моё. Не знал, что там есть применение sed-у.

Занят в embedded разработке под arm, phytec и т.п. Частенько приходилось в загрузочных скриптах или сервисных скриптах задействовать sed для автоматического парсинга логов, конфигурационных параметров системы и т.п. Утилиту sed очень удобно применять, когда входные данные на лету требуется преобразовать к требуемому для последующей переработки виду. Где кроется гемор с регулярными выражениями, так это в случаях, когда требуется автоматическое сервисное обслуживание устройств в сети по ssh. При необходимости передачи вложенных скриптовых выражений, которые частично должны интерпретироваться как чистый текст с необходимостью использования символов экранирования, а частично как команды подстановки. У меня бывали случаи, когда использование одного экранирующего символа "\" в исходном выражении могло приводить к преобразованию его к "\\\" для передачи выражения по ssh, в отдельных случаях неявное поведение баша вообще не позволяло сделать корректное эквивалентное преобразование команд для передачи по ssh. Честно говоря, регулярные выражения мне нравятся ровно до тех пор, пока из них не требуется сформировать более менее сложную команду. Это чуть ли не единственная для шелла вещь из области "Использовал при написании в скрипте, а потом через пол-года не можешь вспомнить, что эта мешанина из спец. и экранирующих символов может значить" XD

Ага. И Вам тоже спасибо!
Я задам, возможно, глупый вопрос -- а файлы, о которых Вы говорите -- загрузочные скрипты, логи и так далее -- они какие по размеру? Сколько строк или килобайт в среднем? Я просто не очень себе представляю.

Ну и мой глупый вопрос -- а почему с этими файлами лучше работать с помощью sed, а не обрабатывать их в Perl или Python?

Я совершенно не представляю специфики, поэтому могу спросить что-то не то. Извиняйте, если что.

Ещё один пример, есть резервная копия базы данных размером в 1 Гб, надо заменить все запросы INSERT на INSERT IGNORE.

Сегодня пришлось заняться: пользователь удалил несколько писем из архива за 2019 год почты Mozilla Thunderbird. Их надо восстановить. В "Удаленные" это письма, почему-то, не попали. Фактически письма всё ещё находятся в файле 2019 размером 9 Гб.
Задача: заменить все строки X-Mozilla-Status: 0009 на X-Mozilla-Status: 0001. mcedit даже на открытии такого файла уже "присел".
И вот решение: sed -i 's/X-Mozilla-Status:\ 0009/X-Mozilla-Status:\ 00091/g' 2019. Пара минут и все удалённые письма восстановлены.

Извините, ошибся: sed -i 's/X-Mozilla-Status:\ 0009/X-Mozilla-Status:\ 0001/g' 2019

В прошлый раз мы говорили о функциях в bash-скриптах, в частности, о том, как вызывать их из командной строки. Наша сегодняшняя тема — весьма полезный инструмент для обработки строковых данных — утилита Linux, которая называется sed. Её часто используют для работы с текстами, имеющими вид лог-файлов, конфигурационных и других файлов.




Если вы, в bash-скриптах, каким-то образом обрабатываете данные, вам не помешает знакомство с инструментами sed и gawk. Тут мы сосредоточимся на sed и на работе с текстами, так как это — очень важный шаг в нашем путешествии по бескрайним просторам разработки bash-скриптов.


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

Основы работы с sed

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


По умолчанию sed применяет указанные при вызове правила, выраженные в виде набора команд, к STDIN . Это позволяет передавать данные непосредственно sed.


Вот что получится при выполнении этой команды.


Простой пример вызова sed

В данном случае sed заменяет слово «test» в строке, переданной для обработки, словами «another test». Для оформления правила обработки текста, заключённого в кавычки, используются прямые слэши. В нашем случае применена команда вида s/pattern1/pattern2/ . Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. Sed, выполняя эту команду, просмотрит переданный текст и заменит найденные в нём фрагменты (о том — какие именно, поговорим ниже), соответствующие pattern1 , на pattern2 .

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

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


Текстовый файл и результаты его обработки

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

Выполнение наборов команд при вызове sed

Для выполнения нескольких действий с данными, используйте ключ -e при вызове sed. Например, вот как организовать замену двух фрагментов текста:


Использование ключа -e при вызове sed

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


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


Другой способ работы с sed

Чтение команд из файла

Если имеется множество команд sed, с помощью которых надо обработать текст, обычно удобнее всего предварительно записать их в файл. Для того, чтобы указать sed файл, содержащий команды, используют ключ -f :

Вот содержимое файла mycommands :


Вызовем sed, передав редактору файл с командами и файл для обработки:


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


Использование файла с командами при вызове sed

Флаги команды замены

Внимательно посмотрите на следующий пример.


Вот что содержится в файле, и что будет получено после его обработки sed.


Исходный файл и результаты его обработки

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

Схема записи команды замены при использовании флагов выглядит так:


Выполнение этой команды можно модифицировать несколькими способами.

  • При передаче номера учитывается порядковый номер вхождения шаблона в строку, заменено будет именно это вхождение.
  • Флаг g указывает на то, что нужно обработать все вхождения шаблона, имеющиеся в строке.
  • Флаг p указывает на то, что нужно вывести содержимое исходной строки.
  • Флаг вида w file указывает команде на то, что нужно записать результаты обработки текста в файл.


Вызов команды замены с указанием позиции заменяемого фрагмента

Тут мы указали, в качестве флага замены, число 2. Это привело к тому, что было заменено лишь второе вхождение искомого шаблона в каждой строке. Теперь опробуем флаг глобальной замены — g :


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


Глобальная замена

Флаг команды замены p позволяет выводить строки, в которых найдены совпадения, при этом ключ -n , указанный при вызове sed, подавляет обычный вывод:


Как результат, при запуске sed в такой конфигурации на экран выводятся лишь строки (в нашем случае — одна строка), в которых найден заданный фрагмент текста.


Использование флага команды замены p

Воспользуемся флагом w , который позволяет сохранить результаты обработки текста в файл:


Сохранение результатов обработки текста в файл

Хорошо видно, что в ходе работы команды данные выводятся в STDOUT, при этом обработанные строки записываются в файл, имя которого указано после w .

Символы-разделители

Представьте, что нужно заменить /bin/bash на /bin/csh в файле /etc/passwd . Задача не такая уж и сложная:


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

К счастью, sed позволяет нам самостоятельно задавать символы-разделители для использования их в команде замены. Разделителем считается первый символ, который будет встречен после s :


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

Выбор фрагментов текста для обработки

До сих пор мы вызывали sed для обработки всего переданного редактору потока данных. В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:

  • Задать ограничение на номера обрабатываемых строк.
  • Указать фильтр, соответствующие которому строки нужно обработать.


Обработка только одной строки, номер который задан при вызове sed

Второй вариант — диапазон строк:


Обработка диапазона строк

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


Обработка файла начиная со второй строки и до конца

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


По аналогии с тем, что было рассмотрено выше, шаблон передаётся перед именем команды s .


Обработка строк, соответствующих фильтру

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

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

Утилита sed годится не только для замены одних последовательностей символов в строках на другие. С её помощью, а именно, используя команду d , можно удалять строки из текстового потока.

Вызов команды выглядит так:


Мы хотим, чтобы из текста была удалена третья строка. Обратите внимание на то, что речь не идёт о файле. Файл останется неизменным, удаление отразится лишь на выводе, который сформирует sed.


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

Если при вызове команды d не указать номер удаляемой строки, удалены будут все строки потока.

Вот как применить команду d к диапазону строк:


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

А вот как удалить строки, начиная с заданной — и до конца файла:


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

Строки можно удалять и по шаблону:


Удаление строк по шаблону

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


Удаление диапазона строк с использованием шаблонов

Вставка текста в поток

С помощью sed можно вставлять данные в текстовый поток, используя команды i и a :

  • Команда i добавляет новую строку перед заданной.
  • Команда a добавляет новую строку после заданной.


Теперь взглянем на команду a :


Как видно, эти команды добавляют текст до или после данных из потока. Что если надо добавить строку где-нибудь посередине?

Тут нам поможет указание номера опорной строки в потоке, или шаблона. Учтите, что адресация строк в виде диапазона тут не подойдёт. Вызовем команду i , указав номер строки, перед которой надо вставить новую строку:


Команда i с указанием номера опорной строки

Проделаем то же самое с командой a :


Команда a с указанием номера опорной строки

Обратите внимание на разницу в работе команд i и a . Первая вставляет новую строку до указанной, вторая — после.

Замена строк

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


Замена строки целиком

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


Замена строк по шаблону

Замена символов

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


Замена символов

Используя эту команду, нужно учесть, что она применяется ко всему текстовому потоку, ограничить её конкретными вхождениями символов нельзя.

Вывод номеров строк

Если вызвать sed, использовав команду = , утилита выведет номера строк в потоке данных:


Вывод номеров строк

Потоковый редактор вывел номера строк перед их содержимым.

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


Вывод номеров строк, соответствующих шаблону

Чтение данных для вставки из файла

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


Вставка в поток содержимого файла

Тут содержимое файла newfile было вставлено после третьей строки файла myfile .

Вот что произойдёт, если применить при вызове команды r шаблон:


Использование шаблона при вызове команды r

Содержимое файла будет вставлено после каждой строки, соответствующей шаблону.

Пример

Представим себе такую задачу. Есть файл, в котором имеется некая последовательность символов, сама по себе бессмысленная, которую надо заменить на данные, взятые из другого файла. А именно, пусть это будет файл newfile , в котором роль указателя места заполнения играет последовательность символов DATA . Данные, которые нужно подставить вместо DATA , хранятся в файле data .

Решить эту задачу можно, воспользовавшись командами r и d потокового редактора sed:


Замена указателя места заполнения на реальные данные

Как видите, вместо заполнителя DATA sed добавил в выходной поток две строки из файла data .

Итоги

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

На сегодня это всё. В следующий раз поговорим о языке обработки данных awk.



Команда tr (translate) используется в Linux в основном для преобразования и удаления символов. Она часто находит применение в скриптах обработки текста. Ее можно использовать для преобразования верхнего регистра в нижний, сжатия повторяющихся символов и удаления символов.

Команда tr требует два набора символов для преобразований, а также может использоваться с другими командами, использующими каналы (пайпы) Unix для расширенных преобразований.

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

Команда tr и ее синтаксис

Ниже приведен синтаксис команды tr. Требуется, как минимум, два набора символов и опции.

SET1 и SET2 это группы символов. are a group of characters. Необходимо перечислить необходимые символы или указать последовательность.

\NNN -> восмеричные (OCT) символы NNN (1 до 3 цифр)

\\ -> обратный слеш (экранированный)

\n -> новая строка (new line)

\r -> перенос строки (return)

\t -> табуляция (horizontal tab)

[:alnum:] -> все буквы и цифры

[:alpha:] -> все буквы

[:blank:] -> все пробелы

[:cntrl:] -> все управляющие символы (control)

[:digit:] -> все цифры

[:lower:] -> все буквы в нижнем регистре (строчные)

[:upper:] -> все буквы в верхнем регистре (заглавные)

Примеры использования команды tr:

Вот некоторые опции:

-c , -C , --complement -> удалить все символы, кроме тех, что в первом наборе
-d , --delete -> удалить символы из первого набора
-s , --squeeze-repeats -> заменять набор символов, которые повторяются, из указанных в последнем наборе знаков

1) Заменить все строчные буквы на заглавные

Мы можем использовать tr для преобразования нижнего регистра в верхний или наоборот.

Просто используем наборы [:lower:] [:upper:] или "a-z" "A-Z" для замены всех символов.

Вот пример, как преобразовать в Linux с помощью команды tr все строчные буквы в заглавные:

А сейчас сделаем замену из файла input.txt

Как мы видим, в файле ничего не изменилось, осталось все строчными буквами. Чтобы изменения были в файле, на необходимо перевести вывод в новый файл. Например, в output.txt


2) Удаление символов с помощью tr

Опция -d используется для удаления всех символов, которые указаны в наборе символов.

Следующая команда удалит все цифры в тексте. Будем использовать набор [:digit:] , чтобы определить все цифры.

А вот пример команд, которыми можно удалить переносы на новые строки


3) Удаление ила змена символов НЕ в наборе

С помощью параметра -c Вы можете сказать tr заменить все символы, которые Вы не указали в наборе. Приведем пример.

А вот пример удаления, просто укажем опцию -d и только один набор (символы которого удалять НЕ надо, а остальные удалить)


4) Замена пробелов на табуляцию

5) Удаление повторений символов

Это делает параметр -s . Рассмотрим пример удаления повторов знаков.

Или заменим повторения на символ решетки

6) Заменить символы из набора на перенос строки

Сделаем так, чтобы все буквы были заменены на перенос новой строки:


7) Генерируем список уникальных слов из файла

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

8) Кодируем символы с помошью ROT

Давайте проверим, как использовать tr для шифрования.

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

Первый набор [a-z] (это значит abcdefghijklmnopqrstuvwxyz). Второй набор [n-za-m] (который содержит pqrstuvwxyzabcdefghijklmn).

Простая команда для демонстрации вышеуказанной теории:

Полезно при шифровании электронных адресов:

Вывод

Если у Вас есть какие-либо дополнения, не стесняйтесь пишите в комментариях.

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