Как использовать sed для поиска и замены строк в файлах

Найти и заменить текст в Linux

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

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

В этой статье мы расскажем, как искать и заменять строки с помощью sed . Мы также покажем, как выполнять рекурсивный поиск и замену.

Найти и заменить строку с помощью sed

Существует несколько версий sed , которые имеют некоторые функциональные различия. В macOS используется версия BSD, в то время как в большинстве дистрибутивов Linux по умолчанию предустановлен GNU sed . Мы будем использовать версию 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 для поиска и замены текста в файлах с некоторыми из ее наиболее часто используемых параметров и флагов.

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

файл.txt

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

 sed -i 's/bfoob/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

Вы также можете использовать регулярные выражения. Например, чтобы найти все трёхзначные числа и заменить их 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

Рекурсивный поиск и замена

Иногда может потребоваться рекурсивно найти в каталогах файлы, содержащие строку, и заменить её во всех файлах. Это можно сделать с помощью таких команд, как find или 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 sed и учебник Grymoire sed .

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

терминал SED

Связанные руководства

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *