Как использовать команду Sed для поиска и замены строк в Linux

12 set 2022 4 min di lettura
Как использовать команду Sed для поиска и замены строк в Linux
Indice dei contenuti

Введение

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

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 также заменяется в предыдущем примере. Если это нежелательное поведение, используйте выражение 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

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

Buy me a coffeeBuy me a coffee

Supportaci se ti piacciono i nostri contenuti. Grazie.

Successivamente, completa il checkout per l'accesso completo a Noviello.it.
Bentornato! Accesso eseguito correttamente.
Ti sei abbonato con successo a Noviello.it.
Successo! Il tuo account è completamente attivato, ora hai accesso a tutti i contenuti.
Operazione riuscita. Le tue informazioni di fatturazione sono state aggiornate.
La tua fatturazione non è stata aggiornata.