Введение
Одна из распространённых задач обработки текста — «найти и заменить». В текстовых редакторах это выполняется интерактивно. В среде командной строки Linux ту же задачу можно выполнять с помощью sed — программируемым неинтерактивным способом.
sed — это неинтерактивный текстовый редактор, который обрабатывает текст построчно. Он особенно полезен для задач подстановки, когда нужно заменить определённые шаблоны новым текстом. Это удобно при автоматизации: человеку не нужно открывать редактор и многократно выполнять одно и то же изменение вручную.
В этой лабораторной работе вы научитесь:
- Подставлять текст (
s): выполнять базовые операции поиска и замены. - Использовать глобальную замену (
g): заменять все вхождения шаблона в строке, а не только первое. - Использовать пользовательские разделители: обрабатывать текст, содержащий косые черты, например пути к файлам, с помощью альтернативных разделителей.
- Редактировать файлы на месте с созданием резервной копии: безопасно изменять файлы, автоматически сохраняя их резервные копии.
Базовая подстановка
Начнём с простой подстановки в строке. Заменим слово «World» на «Linux».
Команда подстановки в sed — s.
Её синтаксис: s/Pattern/Replacement/.
Такая форма команды настолько распространена, что многие считают sed инструментом для поиска и замены. На самом деле это потоковый редактор. Подстановка — лишь одна из наиболее часто используемых команд редактирования.
Выполните следующую команду:
echo "Hello World" | sed 's/World/Linux/'
Как это работает:
echoотправляет строку"Hello World"в стандартный вывод.- Конвейер
|передаёт этот вывод командеsed. sedчитает текст, находит шаблон"World", заменяет его на"Linux"и выводит результат.
Примечание: эта команда не изменяет исходный источник навсегда. Она только выводит изменённый текст на экран — в стандартный вывод (Standard Output).
Это различие важно для безопасного редактирования в командной строке. В Unix-подобных системах инструменты часто сначала показывают преобразованный поток, а уже затем вы решаете, нужно ли сохранить или перенаправить результат.
Глобальная замена
По умолчанию sed заменяет только первое найденное совпадение в каждой строке.
Если строка содержит текст "apple apple" и вы заменяете "apple" на "orange", sed выведет "orange apple".
Чтобы заменить все вхождения в строке, добавьте глобальный флаг (g) в конец команды подстановки.
Важно, что замена выполняется «в каждой строке». sed обрабатывает текст построчно, поэтому флаг g влияет на все совпадения в текущей строке, а не на весь файл как на единый блок текста.
Проверим содержимое примера файла quote.txt:
cat quote.txt
Вывод: I love Coding. Coding is fun.
Теперь замените "Coding" на "Programming" без глобального флага:
sed 's/Coding/Programming/' quote.txt
Результат: I love Programming. Coding is fun.
Обратите внимание: второе вхождение "Coding" не было заменено.
Теперь добавьте флаг g:
sed 's/Coding/Programming/g' quote.txt
Результат: I love Programming. Programming is fun.
Теперь оба вхождения успешно заменены.
Использование других разделителей
Стандартный синтаксис sed использует косые черты / в качестве разделителей: s/old/new/.
Однако если заменяемый текст содержит косые черты, например путь к файлу /usr/local/bin, то каждую косую черту пришлось бы экранировать обратной косой чертой. Из-за этого команда становится трудной для чтения: s/\/usr\/local\/bin/\/bin/.
К счастью, sed позволяет использовать в качестве разделителя почти любой символ. Распространённые варианты — #, : и |.
Выбор понятного разделителя — это практический навык, а не просто синтаксический приём. Если шаблоны содержат много символов /, смена разделителя делает команду более понятной и снижает вероятность ошибки.
Создайте файл, содержащий путь:
echo "/usr/local/bin" > path.txt
Теперь замените /usr/local/bin на /bin, используя # в качестве разделителя:
sed 's#/usr/local/bin#/bin#' path.txt
Результат: /bin
Поскольку мы использовали # как разделитель, sed воспринял символы / в пути как обычный текст. Поэтому команда получилась короче и легче для чтения.
Редактирование на месте с созданием резервной копии
До этого sed только выводил изменения на экран. Чтобы изменить файл напрямую, то есть выполнить редактирование на месте, используйте параметр -i.
Однако прямое изменение файлов может быть рискованным. Если вы ошибётесь в шаблоне, можно потерять данные. Поэтому перед изменением файла желательно создать резервную копию исходного содержимого.
Для этого передайте расширение параметру -i, например -i.bak.
Изменим quote.txt и автоматически создадим резервную копию с именем quote.txt.bak.
sed -i.bak 's/fun/awesome/' quote.txt
Теперь проверьте содержимое изменённого файла:
cat quote.txt
Результат: I love Coding. Coding is awesome.
Затем убедитесь, что резервная копия существует и содержит исходный текст:
ls -l quote.txt.bak
cat quote.txt.bak
Результат: I love Coding. Coding is fun.
Это хорошая практика при пакетном редактировании нескольких файлов.
Такая привычка создавать резервные копии особенно важна потому, что неинтерактивное редактирование выполняется быстро, но не прощает ошибок. При автоматической замене текста в нескольких файлах небольшая ошибка в шаблоне может быстро распространиться, поэтому сохранение исходной копии — простой способ повысить безопасность.
Итоги
В этой лабораторной работе вы изучили основные возможности подстановки текста с помощью sed:
- Подстановка (
s///): стандартная команда для поиска и замены текста. - Глобальный флаг (
g): замена всех вхождений шаблона в строке. - Пользовательские разделители: использование таких символов, как
#, для безопасной обработки путей и URL, содержащих/. - Резервная копия при редактировании на месте (
-i.bak): безопасное изменение файлов с сохранением исходного содержимого.
Эти навыки позволяют эффективно и безопасно автоматизировать сложные задачи обработки текста.



