Как использовать sed для поиска и замены строки в файлах
Как использовать sed для поиска и замены строки в файлах
How to Use sed to Find and Replace String in Files
В этой статье мы поговорим о том, как найти и заменить строки sed. Мы также покажем вам, как выполнять рекурсивный поиск и замену.

Довольно часто при работе с текстовыми файлами вам нужно находить и заменять строки текста в одном или нескольких файлах.
sed
может выполнять основные операции с текстом над файлами и входными потоками, такими как конвейеры. С sed
его помощью вы можете искать, находить и заменять, вставлять и удалять слова и строки. Он поддерживает базовые и расширенные регулярные выражения, которые позволяют сопоставлять сложные шаблоны.
Найти и заменить строку на sed
Существует несколько версий sed
, с некоторыми функциональными различиями между ними. macOS использует версию BSD, и большинство дистрибутивов Linux поставляются с sed
предварительно установленной GNU по умолчанию. Мы будем использовать версию GNU.
Общая форма поиска и замены текста sed
принимает следующую форму:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i
- По умолчаниюsed
записывает свой вывод на стандартный вывод. Эта опция говоритsed
редактировать файлы на месте. Если указано расширение (например, -i.bak), будет создана резервная копия исходного файла.s
- Команда замены, вероятно, наиболее используемая команда в sed./ / /
- разделитель персонажа. Это может быть любой символ, но обычно используется/
символ косой черты ( ).SEARCH_REGEX
- Обычная строка или регулярное выражение для поиска.REPLACEMENT
- Строка замены.g
- Глобальный флаг замены. По умолчаниюsed
файл читает построчно и изменяет только первое вхождениеSEARCH_REGEX
строки. Если указан флаг замены, все случаи будут заменены.INPUTFILE
- Имя файла, для которого вы хотите выполнить команду.
Хорошей практикой является размещение кавычек вокруг аргумента, чтобы метасимволы оболочки не расширялись.
Давайте посмотрим примеры того, как использовать sed
команду для поиска и замены текста в файлах с некоторыми из его наиболее часто используемых опций и флагов.
В демонстрационных целях мы будем использовать следующий файл:
123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
Если вы опустите g
флаг, будет заменен только первый экземпляр строки поиска в каждой строке:
sed -i 's/foo/linux/' file.txt
123 Foo linux foo
linux /bin/bash Ubuntu foobar 456
С глобальным флагом замены sed
заменяет все вхождения шаблона поиска:
sed -i 's/foo/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456
Как вы могли заметить, в предыдущем примере подстрока foo
внутри foobar
строки также заменяется. Если это нежелательное поведение, используйте выражение word-boundery ( \b
) на обоих концах строки поиска. Это гарантирует, что отдельные слова не совпадают.
sed -i 's/\bfoo\b/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu foobar 456
Чтобы сделать сопоставление с шаблоном нечувствительным к регистру, используйте I
флаг. В приведенном ниже примере мы используем как g
и I
флаги:
sed -i 's/foo/linux/gI' file.txt
123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456
Если вы хотите найти и заменить строку, содержащую символ-разделитель ( /
), вам нужно использовать обратную косую черту ( \
), чтобы избежать косой черты. Например , чтобы заменить /bin/bash
с /usr/bin/zsh
вы будете использовать
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
Более простой и читаемый вариант - использовать другой символ-разделитель. Большинство людей используют вертикальную черту ( |
) или двоеточие ( :
), но вы можете использовать любой другой символ:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456
Вы также можете использовать регулярные выражения. Например, чтобы найти все 3-значные числа и заменить их строкой, которую number
вы используете:
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
number Foo foo foo
foo /bin/bash demo foobar number
Еще одна полезная функция sed - вы можете использовать символ амперсанда, &
который соответствует согласованному шаблону. Персонаж может быть использован несколько раз.
Например, если вы хотите добавить фигурные скобки {}
вокруг каждого трехзначного числа, введите:
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
{123} Foo foo foo
foo /bin/bash demo foobar {456}
И последнее, но не менее важное: всегда полезно сделать резервную копию при редактировании файла с помощью sed
. Для этого просто предоставьте расширение -i
опции. Например, чтобы отредактировать file.txt
и сохранить исходный файл, как file.txt.bak
вы бы использовали:
sed -i.bak 's/foo/linux/g' file.txt
Если вы хотите убедиться, что резервная копия создана, перечислите файлы с помощью ls
команды:
ls
file.txt file.txt.bak
Рекурсивный поиск и замена
Иногда вы хотите рекурсивно искать в каталогах файлы, содержащие строку, и заменять строку во всех файлах. Это можно сделать с помощью таких команд, как grep
чтобы рекурсивно найти файлы в каталоге и передать имена файлов в sed
.
Следующая команда будет рекурсивно искать файлы в текущем рабочем каталоге и передавать имена файлов в sed
.
find . -type f -exec sed -i 's/foo/bar/g' {} +
Чтобы избежать проблем с файлами, содержащими пробел в их именах, используйте -print0
опцию, которая указывает find
печатать имя файла, за которым следует нулевой символ и направлять вывод в sed
использование xargs -0
:
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Чтобы исключить каталог, используйте -not -path
опцию. Например, если вы заменяете строку в локальном git-репо, чтобы исключить все файлы, начинающиеся с точки ( .
), используйте:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
Если вы хотите искать и заменять текст только в файлах с определенным расширением, вы должны использовать:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Другой вариант - использовать grep
команду для рекурсивного поиска всех файлов, содержащих шаблон поиска, а затем передать имена файлов по адресу sed
:
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
Вывод
Хотя это может показаться сложным и сложным, сначала поиск и замена текста в файлах sed
очень просты.
Чтобы узнать о более sed
команд, опции и флаги посетить GNU СЭД руководство и Grymoire СЭД учебник .