sed вывести строку по номеру
Bash-скрипты: sed и обработка текстов
В прошлый раз мы говорили о функциях в bash-скриптах, в частности, о том, как вызывать их из командной строки. Наша сегодняшняя тема — весьма полезный инструмент для обработки строковых данных — утилита Linux, которая называется sed. Её часто используют для работы с текстами, имеющими вид лог-файлов, конфигурационных и других файлов.
Если вы, в bash-скриптах, каким-то образом обрабатываете данные, вам не помешает знакомство с инструментами sed и gawk. Тут мы сосредоточимся на sed и на работе с текстами, так как это — очень важный шаг в нашем путешествии по бескрайним просторам разработки bash-скриптов.
Сейчас мы разберём основы работы с sed, а так же рассмотрим более трёх десятков примеров использования этого инструмента.
Основы работы с sed
Утилиту sed называют потоковым текстовым редактором. В интерактивных текстовых редакторах, наподобие nano, с текстами работают, используя клавиатуру, редактируя файлы, добавляя, удаляя или изменяя тексты. Sed позволяет редактировать потоки данных, основываясь на заданных разработчиком наборах правил. Вот как выглядит схема вызова этой команды:
Вот что получится при выполнении этой команды.
Простой пример вызова sed
Выше приведён примитивный пример использования sed, нужный для того, чтобы ввести вас в курс дела. На самом деле, sed можно применять в гораздо более сложных сценариях обработки текстов, например — для работы с файлами.
Ниже показан файл, в котором содержится фрагмент текста, и результаты его обработки такой командой:
Команда Sed в Linux, вывод текста, удаление, замена.
Потоковый редактор sed (stream editor) — это текстовый редактор, выполняющий операции редактирования над информацией в стандартном потоке ввода или файле. Редактирование осуществляется по одной строке и неинтерактивно. Это означает, что вы принимаете все решения по редактированию при запуске команды, а утилита автоматически выполняет ваши указания. Это может показаться непонятным и неинтуитивным, но на самом деле sed — очень мощный и быстрый инструмент для преобразования текста.
В данном руководстве мы рассмотрим ряд базовых операций и познакомимся с необходимым синтаксисом. Утилита вряд ли заменит ваш обычный текстовый редактор, но скорее всего станет полезным дополнением к вашим инструментам для работы с текстами.
Синтаксис Sed
Обычно sed работает с потоком текста, считываемым из стандартного ввода или файла. Это значит, что вы можете отправить выходные данные другой команды непосредственно на вход утилиты для редактирования или работать с уже созданным файлом. Вывод всех результатов по умолчанию осуществляется в стандартный поток вывода, то есть выходные данные будут выведены на экран, а не сохранены в файл, если их не перенаправить.
Синтаксис команды следующий:
Скопируем себе в домашнюю директорию несколько файлов, чтобы попрактиковаться в редактировании.
Воспользуемся утилитой для просмотра содержимого скопированной нам лицензии BSD. По умолчанию sed выводит результаты на экран, поэтому им можно пользоваться для просмотра файлов, не задавая команд редактирования:
Это работает из-за того, что одиночные кавычки содержат команды редактирования, передаваемые sed. Мы ничего не передали, поэтому утилита просто вывела каждую полученную строку в стандартный поток вывода. Теперь покажем, как утилита может использовать стандартный ввод. Перенаправим редактору выходные данные команды “cat” и получим тот же результат.
Copyright (c) The Regents of the University of California.
All rights reserved.
Мы можем работать с файлами или потоками текста (как происходит при перенаправлении вывода символом «|») одинаково легко.
Вывод строк
В предыдущем примере мы показали, что передаваемые без команд входные данные напрямую выводятся в стандартный поток вывода.Теперь рассмотрим явную команду “print”, которая задаётся при помощи символа “p” в одиночных кавычках.
Теперь утилита выводит каждую строку дважды. Это происходит потому, что каждая строка выводится автоматически, а ещё мы в явном виде указали выводить их командой “p”. Если посмотреть на результат, где дважды напечатана первая строка, затем дважды вторая и т.д., можно заметить, что sed работает построчно. Он принимает строку, обрабатывает ее и выводит результат, затем процесс повторяется для следующей строки.
Указав sed опцию «-n», которая отключает автоматический вывод, мы можем очистить результат:
Каждая строка снова выводится один раз.
Диапазоны адресов
Рассмотренные выше примеры вряд ли можно назвать редактированием (если мы не хотели выводить каждую строку два раза). Давайте изменим результат, указав sed напечатать только первую строку.
Число «1» перед командой вывода указывает номер строки для работы. Таким же образом мы можем вывести пять строк (не забываем про «-n»).
Мы только что передали в утилиту адрес. При получении адреса редактор выполняет указанные далее команды только над этими строками. В данном примере мы указали начальный адрес и смещение, чтобы сообщить команде, сколько ещё строк она должна пройти:
Результат будет таким же, потому что мы указали начать с первой строки и обработать следующие 4.
Если нужно исключить какие-то строки, можно указать интервал после символа «
».
Следующая команда напечатает все нечетные строки, начиная с первой:
Удаление текста
Можно легко удалить текст, который мы выводили в предыдущем примере, заменив команду “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”.
Если нужно заменить текст во всех файлах директории то можно воспользоваться командой
Про утилиту grep можно прочитать здесь
Заключение
Мы рассмотрели основы использования sed. Теперь вы можете быстро редактировать текстовые документы при помощи соответствующих команд sed.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Примеры команды Sed
Полезные однострочные скрипты для sed (потокового редактора Unix), составленные Эриком Пементом
Есть несколько программ, которые являются настоящими рабочими лошадками в обойме UNIX. Эти программы просты в использовании для простых действий, хотя они имеют богатый набор команд для выполнения комплексных действий. Не нужно пренебрегать изучением потенциала программ, ведь очень часто получается, что кто-то пишет свою функцию или подпрограмму, а, оказывается, всё уже давно написано, что уже есть программа, которая делает это в одну строку, но нужно знать эту программу, знать с какими ключами её запустить.
Sed — это первичный потоковый редактор.
Потоковый редактор sed — это текстовый редактор, которые выполняет операции редактирования информации поступающей из стандартного ввода или из файла. Это означает, что вы можете отправлять вывод другой команды прямо на sed для редактирования, или вы можете работать с файлом, который вы уже создали. Также важно помнить, что по умолчанию sed всё выводит также в стандартный вывод. Это означает, что если не сделан редирект, sed будет печатать вывод на экран, вместо того, чтобы сохранить в файл.
Sed редактирует построчно и в неинтерактивном режиме.
Переводы строк в файле:
Удвоение перевода строк:
Удвоение перевода строк в файле, который уже имеет пустые строки. Конечный файл должен содержать не более чем одну пустую строку между двумя строками текста.
Утроение перевода строк
Отмена удвоения строк (предполагается, что чётные строки всегда пустые)
Вставить пустую строку над каждой строкой, которая соответствует “regex”
Вставить пустую строку под каждой строкой, которая соответствует “regex”
Вставить пустую строку над и под каждой строкой, которая соответствует “regex”
Нумерация:
Пронумеровать каждою строку в файле (просто в левой стороне будут цифры). Использование отступа вместо пробела сохраняет ровное начало строк.
Пронумеровать каждую строку в файле (номера слева, выравнивание по правому краю)
Пронумеровать каждую строку файла, но печатать номер только если строка не пустая
Преобразования текста и подстановки:
В окружении 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”)
Напечатать последние 10 строк файла (эмулирует “tail”)
Напечатать строки файла начиная с последней
Для файла в одну строку напечатать пустую строку
Для файла в одну строку, напечатать эту строку:
Для файла в одну строку ничего не печатать
Печатать только строки, которые соответствуют регулярному выражению (эмулирует “grep”)
Метод 1, соответствует вышеприведённому
Метод 2, упрощённый синтаксис
Печатать строку, которая идёт перед строкой, удовлетворяющей регулярному выражению, но не строку, содержащую регулярное выражение
Печатать строку, которая идёт сразу после регулярного выражения, но не строку, содержащую регулярное выражение
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, упрощённый синтаксис
Напечатать секцию файла от регулярного выражения до конца файла
Напечатать секцию файла, включающую номера строк (строки 8-12, включая и 8 и 12)
Напечатать строку с номером 52
Способ 3, эффективен на больших файлах
Начиная со строки 3, печатать каждую седьмую строку
Напечатать раздел файла между двумя регулярными выражениями (включая)
Выборочное удаление конкретных строк:
Напечатать весь файл КРОМЕ секции между двумя регулярными выражениями 2
Удалить дубликаты последовательных строк файла (эмулирует “uniq”). Первая строка из двух дублирующих сохраняется, остальное удаляется.
Удалить дубликаты непоследовательных строк из файла. Остерегайтесь переполнения буфера или используйте GNU sed.
Удалить первые 10 строк файла
Удалить последние строки файла
Удалить последние 2 строки файла
Удалить последние 10 строк файла
Удалить каждую восьмую строку файла
Удалить строки, содержащие паттерн
Удалить ВСЕ пустые строки из файла (то же самое что и “grep ‘.’ “)
Способ 1, позволяет 0 пустых строк вверху, 1 в EOF
Способ 2, позволяет 1 пустую строку вверху, 0 в EOF
Удалить все ПОСЛЕДОВАТЕЛЬНЫЕ пустые строки из файла кроме первых двух:
Удалить все первые пустые строки в файле
Удалить все конечные пустые строки в файле
Удалить последнюю строку каждого параграфа
Специальные приложения:
Требуются двойные кавычки для окружения Unix
в bash/tcsh, нажмите Ctrl-V, а затем Ctrl-H
hex выражения для sed 1.5, GNU sed, ssed
Получить заголовки Usenet/e-mail сообщений
Получить тело Usenet/e-mail сообщений
Получает Тему из заголовка, но удаляет первоначальное “Subject: ”
Получает обратный адрес отправителя из заголовка
Разбирает поле адрес. Достаёт чистый e-mail адрес из первой строки, которая включает в себя кусок заголовка (смотрите предыдущий скрипт)
Добавить ведущую скобку и пробел для каждой строки (цитата сообщения)
Удалить ведущую скобку и пробел для каждой строки (расцитативание)
Удаление большинства HTML тэгов (включая многострочные тэги)
Извлечение нескольких частей двоичных файлов, представленных методом UUE, удаление посторонних данных заголовка так, что остаётся только закодированные в UUE данные. Фалы, передаваемые sed, должны быть переданы в правильном порядке. Версия 1 может быть введена в командную строку; версия 2 может быть исполнена в скрипте оболочки Unix
Отсортировать параграфы файла в алфавитном порядке. Параграфы разделяются пустой строкой. GNU sed использует \v для вертикального таба, или может применяться любой другой уникальный символ.
Sed вывести строку по номеру
Программа sed способна выполнять сложные задания, и нужно потратить время, чтобы научиться эти задания формулировать.
Но наряду со сложными действиями, у команды sed есть простые, но весьма полезные возможности, освоить которые не труднее, чем прочие команды Юникс. Не позволяйте себе из-за сложности освоения всей программы, отказываться от ее простых аспектов.
Мы начнем от простого к сложному, так что вы всегда сможете понять, где следует остановиться.
Программа sed имеет множество собственных команд. Большинство пользователей знают только команду s, и этого вполне хватает, чтобы работать с редактором sed. Команда s заменяет ОБРАЗЕЦ на ЗАМЕНУ:
Проще не бывает. А вот пример с вводом из файла zar.txt:
Я не брал выражение s/ОБРАЗЕЦ/ЗАМЕНУ/ в кавычки, так как данный пример не нуждается в кавычках, но если бы в нем присутствовали метасимволы, то кавычки были бы обязательны. Чтобы не ломать себе каждый раз голову, и не ошибиться ненароком, всегда ставьте кавычки, лучше более «сильные» одинарные, это хорошая привычка. Кашу маслом не испортишь. Я тоже во всех последующих примерах не буду манкировать кавычками.
Как мы видим, заменяющая команда s имеет четыре составляющих:
Это называется «частокол» и выглядит весьма уродливо, а главное, непонятно.
Уникальность программы sed в том, что она позволяет использовать любой разделитель, например знак подчеркивания:
Если в поисках разделителя, который вам нравится, вы получаете сообщение «незавершенная команда `s'», значит этот символ не годится в качестве разделителя, или вы просто забыли поставить один-два разделителя.
В этой статье я вынужден использовать традиционный разделитель (/) чтобы не сбивать читателя с толку, но в случае необходимости стану использовать в качестве разделителя тильду (
Регулярные выражения (РВ)
(Regular expressions, regexp, RE)
Тема регулярных выражений настолько обширна, что ей посвящены целые книги (смотри ссылки в конце статьи). Тем не менее, говорить всерьез о редакторе sed, не применяя регулярных выражений, также непродуктивно, как разговаривать о тригонометрии при помощи счетных палочек. Поэтому необходимо рассказать хотя бы о тех регулярных выражениях, которые часто используются с программой sed.
с Или любая другая буква. Большинство букв, цифр и прочих неспециальных символов считаются регулярными выражениями, представляющими сами себя.
* Астериск, следующий за каким-либо символом или регулярным выражением, означает любое число (в том числе и нулевое) повторов этого символа или регулярного выражения.
\+ Означает один или более повтор символа или регулярного выражения.
\? Означает ни одного или один повтор.
\ Означает ровно i повторов.
\ Число повторов находится в интервале от i до j включительно.
\ Число повторов больше или равно i.
\<,j\> Число повторов меньше или равно j.
\(RE\) Запомнить регулярное выражение или его часть с целью дальнейшего использования как единое целое. Например, \(а-я\)* будет искать любое сочетание любого количества (в том числе и нулевого) строчных букв.
. Означает любой символ, в том числе символ новой строки.
^ Означает нулевое выражение в начале строки. Другими словами, то, перед чем стоит этот знак, должно появляться в начале строки. Например, ^#include будет искать строки, начинающиеся с #include.
$ То же, что и предыдущее, только относится к концу строки.
[СПИСОК] Означает любой символ из СПИСКА. Например, [aeiou] будет искать любую английскую гласную букву.
RE1\|RE2 Означает РВ1 или РВ2.
RE1RE2 Означает объединение регулярных выражений РВ1 и РВ2.
\n Означает символ новой строки.
Внимание: Остальные условные обозначения на основе обратного слэша (\), принятые в языке С, не поддерживаются программой sed.
\1 \2 \3 \4 \5 \6 \7 \8 \9 Означает соответствующую по счету часть регулярного выражения, запомненную при помощи знаков \( и \).
abcdef Означает abcdef
a*b Означает ноль или любое количество букв а и одна буква b. Например, aaaaaab; ab; или b.
a\?b Означает b или ab
a\+b\+ Означает одну или больше букв а и одну или больше букв b. Например: ab; aaaab; abbbbb; или aaaaaabbbbbbb.
.* Означает все символы на строке, на всех строках, включая пустые.
.\+ Означает все символы на строке, но только на строках, содержащих хотя бы один символ. Пустые строки не соответствуют данному регулярному выражению.
^main.*(.*) Будет искать строки, начинающиеся со слова main, а также имеющие в своем составе открывающую и закрывающие скобки, причем перед и после открывающей скобки может находиться любое количество символов (а может и не находиться).
^# Будет искать строки, начинающиеся со знака # (например комментарии).
\\$ Будет искать строки, заканчивающиеся обратным слэшем (\).
[a-zA-Z_] Любые буквы или цифры
^.*A.*$ Означает заглавную букву А точно в середине строки.
A.\<9\>$ Означает заглавную букву А, точно десятую по счету от конца строки.
^.\<,15\>A Означает заглавную букву А, точно шестнадцатую по счету от начала строки.
Теперь, когда мы познакомились с некоторыми регулярными выражениями, вернемся к команде s редактора sed.
Символ & (амперсанд), будучи помещен в состав ЗАМЕНЫ, означает любой найденный в тексте ОБРАЗЕЦ. Например:
Звездочка (астериск) после интервала 4 нужна чтобы заменены были все цифры, встретившиеся в образце. Без нее получилось бы:
То есть в качестве образца взята была первая же найденная цифра.
Вот пример со вполне осмысленной нагрузкой: составим файл formula.txt:
и применим к нему команду:
Математическая формула приобрела однозначный смысл.
Еще символ амперсанда можно использовать для удвоения ОБРАЗЦА:
Тут есть одна тонкость. Если мы чуть усложним пример:
как и следовало ожидать, удваиваются только цифры, так как в ОБРАЗЦЕ нет букв. Но если мы поменяем части текста местами:
тогда цифры будут удваиваться, независимо от количества предшествующих «слов».
Использование условных знаков \(, \) и \1 для обработки части ОБРАЗЦА Условные знаки \( и \) (escaped parentheses) применяются для запоминания части регулярного выражения.
Для того, чтобы поменять слова местами, нужно запомнить два суб-ОБРАЗЦА, а потом поменять их местами:
Знак \1 вовсе не обязан быть только в ЗАМЕНЕ, он может присутствовать также и в ОБРАЗЦЕ, например, когда мы хотим удалить дубликаты слов:
Модификаторы замены команды s
Модификаторы замены ставятся после последнего разделителя. Эти модификаторы определяют действия программы в случае, если в строке нашлось более одного совпадения с ОБРАЗЦОМ, и каким образом производить замену.
— Глобальная замена (Global replacement)
Программа sed, как и большинство утилит Юникс, при работе с файлами считывают по одной строке. Если мы приказываем заменить слово, программа заменит только первое совпавшее с ОБРАЗЦОМ слово на данной строке. Если мы хотим изменить каждое слово, совпавшее с образцом, то следует ввести модификатор /g.
Без модификатора /g:
Редактор заменил только первое совпавшее слово.
А теперь с модификатором глобальной замены:
Все совпадения в данной строке были заменены.
А если нужно изменить все слова, скажем взять их в скобки? Тогда на помощь снова придут регулярные выражения. Чтобы выбрать все буквенные символы, как верхнего, так и нижнего регистра, можно воспользоваться конструкцией [А-Яа-я], но в нее не попадут такие слова как «что-то» или «с’езд». Гораздо удобнее конструкция [^ ]*, которая соответствует всем символам, кроме пробела. Итак:
Как выбрать нужное совпадение из нескольких
В этом примере мы запомнили оба слова, и, поставив второе (пингвин) на первое место, первое (глупый) удалили, поставив в секции ЗАМЕНЫ вместо него пробел. Если мы поставим вместо пробела какое-либо слово, то оно заменит первое (глупый):
В этом примере каждое слово является совпадением, и мы указали редактору, какое по счету слово мы хотим заменить, поставив модификатор 2 после секции ЗАМЕНЫ.
Можно комбинировать цифровой модификатор с модификатором /g. Если нужно оставить неизменным первое слово, а второе и последующие заменить на слово «(удалено)», то команда будет такая:
Если нужно действительно удалить все последующие совпадения, кроме первого, то в секции ЗАМЕНЫ следует поставить пробел:
Или вовсе ничего не ставить:
Числовой модификатор может быть любым целым числом от 1 до 512. Например, если нужно поставить двоеточие после 80 символа каждой строки, то поможет команда:
Позволяет записывать результаты обработки текста в указанный файл:
Модификатор /e (расширение GNU)
Позволяет указать команду шелла (не программы sed) в качестве ЗАМЕНЫ. Если соответствие ОБРАЗЦУ будет найдено, то оно будет заменено на вывод указанной в секции ЗАМЕНЫ команды. Пример:
Модификаторы /I и /i (расширение GNU)
Делают процесс замены нечувствительным к регистру символов.
Модификаторы можно комбинировать, когда это имеет смысл. При этом следует ставить модификатор w последним.
Условные обозначения (расширение GNU) Их всего пять:
\L переводит символы ЗАМЕНЫ в нижний регистр \l переводит следующий символ ЗАМЕНЫ в нижний регистр \U переводит символы ЗАМЕНЫ в верхний регистр \u переводит следующий символ ЗАМЕНЫ в верхний регистр \E отменяет перевод, начатый \L или \U По очевидным причинам эти условные обозначения применяются по одиночке. Например:
Мы рассмотрели почти все аспекты команды s редактора sed. Теперь настала очередь рассмотреть опции этой программы.
Опции программы sed
Назвать скрипт можно как угодно, важно не путать файл скрипта с обрабатываемым файлом.
Так как совпадений с ОБРАЗЦОМ не найдено (в файле нет цифр), то команда s с модификатором /p и знаком & в качестве ЗАМЕНЫ (напомню, что амперсанд означает сам ОБРАЗЕЦ), работает как команда cat.
Если ОБРАЗЕЦ будет найден в файле, то строки, содержащие ОБРАЗЕЦ, будут удвоены:
Выбор нужных элементов редактируемого текста
Используя лишь одну команду s, мы убедились в необыкновенно широких возможностях редактора sed. А ведь все, что он делает, сводится к поиску и замене. Причем в процессе работы sed редактирует каждую строку поодиночке, не обращая внимания на другие. Было бы удобно ограничить круг строк, подлежащих изменению, например:
Программа sed умеет все это и даже больше. Любая команда редактора sed может применяться адресно, в некотором диапазоне адресов, или с вышеперечисленными ограничениями круга строк. Адрес или ограничение должны непосредственно предшествовать команде:
Выбор строк по номерам
Это самый простой случай. Просто указываем номер нужной строки перед командой:
Выбор строк в диапазоне номеров
Диапазон указывается, как не удивительно, через запятую:
Выбор строк, содержащих некое выражение
Искомое выражение заключается в прямые слэши (/) и ставится перед командой:
Выбор строк в диапазоне между двумя выражениями
Также как и в случае с номерами строк, диапазон задается через запятую:
Выбор строк от начала файла и до некоего выражения
Выбор строк от некоего выражения и до конца файла
Другие команды редактора sed
Удаляет из стандартного вывода указанные строки:
Причем чаще пишут проще (без пробела):
Все, что было сказано в предыдущем разделе о адресации строк, справедливо и для команды d (как и для почти всех команд редактора sed).
При помощи команды d удобно выбросить ненужную «шапку» какого-нибудь почтового сообщения:
(Удалить строки с первой и до первой пустой строки).
Избавится от комментариев в конфигурационном файле:
И мало ли, где нужно удалить лишние строчки!
Английское слово «print» переводится как «печатать», что в русском языке ассоциируется с принтером, или, по крайней мере, с клавиатурой. На самом же деле, слово это в английском контексте зачастую означает просто вывод на экран монитора. Так что команда p ничего не печатает, а просто выводит на экран указанные строки.
Будучи примененной сама по себе, команда p удваивает строки в выводе (ведь программа sed по умолчанию выводит строку на экран, а команда p выводит ту же строку вторично).
Этому свойству находится применение, например удвоить пустые строки для улучшения вида текста:
Например, просмотреть строки с первой по десятую:
Или только комментарии:
Иногда нужно бывает редактировать все строки, кроме тех, что соответствуют ОБРАЗЦУ, либо выбору. Символ восклицательного знака (!) инвертирует выбор. Например удалим все строки, кроме второй из четверостишия Гумилева:
Или выберем все строки, кроме комментариев, из файла /boot/grub/menu.lst:
Команда q прекращает работу программы sed после указанной строки. Это удобно, если нужно прекратить редактирование после достижения определенного места в тексте:
Эта команда закончит работу по достижению 11-й строки.
Подобно модификатору w команды s, эта команда позволяет записать вывод программы в файл:
Для работы в командной строке, удобнее пользоваться обычным перенаправлением вывода (> или >>), но в sed скриптах, вероятно, команда w найдет свое применение.
Эта команда не только прочтет указанный файл, но и вставит его содержимое в нужное место редактируемого файла. Для выбора «нужного места» используется уже знакомая нам адресация (по номерам строк, по выражениям, и проч.). Пример:
Из стихотворения Гумилева:
Выдаст номер указанной строки:
Команда принимает только один адрес, не принимает интервалов.
Эта команда заменяет символы из секции ОБРАЗЕЦ символами секции ЗАМЕНА, работая как программа tr.
Команда y работает, только если количество символов в ОБРАЗЦЕ равно количеству символов в ЗАМЕНЕ.
Скрипты программы sed
Для того, чтобы пользоваться редактором sed как полноценным текстовым редактором, необходимо освоить составление скриптов sed. Программа sed имеет собственный несложный язык программирования, позволяющий составлять скрипты, способные творить чудеса.
Эта статья не может вместить описания скриптов sed, как и ее автор не ставит себе задачу освоение языка программирования sed. В этой статье я делал акцент на использование редактора sed в командной строке, имея прицел на использование его в качестве фильтра в программных каналах (pipes). По этой причине я опустил многочисленные команды sed, применяющиеся только в его скриптах.
Существует множество любителей редактора sed, и множество статей на тему скриптописания, в том числе и в Рунете. Так что для заинтересовавшихся этой замечательной программой не составит труда пополнить свои знания.
Программа sed и символы кириллицы
Как видно из примеров в этой статье, программа sed на правильно русифицированной системе свободно владеет «великим и могучим» языком.
Резюме программы sed
Для освоения программы sed в полном объеме потребуются недели или даже месяцы работы, так как для этого необходимо:
С другой стороны, освоить несколько наиболее употребительных команд редактора sed не сложнее, чем любую команду Юникс; надеюсь, данная статья поможет вам в этом.
Послесловие
До сих пор, в статьях цикла HuMan, я стремился хотя бы вкратце раскрыть каждую опцию, каждый параметр описываемой команды, так чтобы статья могла заменить маны. В дальнейшем я буду продолжать придерживаться этого принципа.
Данная статья является исключением, так как не описывает всех возможностей программы. Для полного их описания потребовалась бы не статья, а книга. Тем не менее, статья позволяет получить представление о редакторе sed и начать работать с этой удивительной программой, используя наиболее употребительные ее команды.