Как выполнить grep и заменить

Мне нужно рекурсивно искать указанную строку во всех файлах и подкаталогах в каталоге и заменять эту строку другой строкой.

Я знаю, что команда для его поиска может выглядеть так:

grep 'string_to_find' -r ./*

Но как я могу заменить каждый экземпляр string_to_find на другую строку?

Ответ 1

Другой вариант - использовать find, а затем передать его через sed.

find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;

Ответ 2

Я получил ответ.

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'

Ответ 3

Вы могли бы даже последовать за этим.

Пример

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

Это приведет к поиску строки " Windows" во всех файлах относительно текущего каталога и заменит " окна" на linux для каждого вхождения строки в каждом файле.

Ответ 5

Обычно не с grep, а скорее с sed -i 's/string_to_find/another_string/g' или perl -i.bak -pe 's/string_to_find/another_string/g'.

Ответ 6

Другие решения сочетают синтаксисы регулярных выражений. Чтобы использовать шаблоны perl/PCRE для и поиска и замены и избежать обработки каждого файла, это работает достаточно хорошо:

grep -rlZP 'match1' | xargs -0r perl -pi -e 's/match2/replace/g;'

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

Перевод: grep рекурсивно и список соответствующих файлов, разделенных nul для защиты любых специальных символов в имени файла, которые соответствуют этому шаблону PCRE, а затем связывают эти имена файлов с xargs, которые ожидают нулевой раздел, но не будут делать ничего, если имена не получены, и получить perl для перезаписи каждого файла, заменяя строки, в которых найдены совпадения.

Добавьте параметр I в grep, чтобы игнорировать двоичные файлы.

Ответ 7

Будьте очень осторожны при использовании find и sed в git-репо! Если вы не исключите двоичные файлы, вы можете получить следующую ошибку:

error: bad index file sha1 signature 
fatal: index file corrupt

Чтобы устранить эту ошибку, вам нужно вернуть sed, заменив new_string на old_string. Это вернет замененные строки, поэтому вы вернетесь к началу проблемы.

Правильный способ поиска и замены строки - пропустить find и использовать вместо него grep, чтобы игнорировать двоичные файлы:

sed -ri -e "s/old_string/new_string/g" $(grep -Elr --binary-files=without-match "old_string" "/files_dir")

Кредиты для @hobs

Ответ 8

Другой вариант - просто использовать perl с globstar.

Включение shopt -s globstar в .bashrc (или везде) позволяет шаблону шара ** соответствовать рекурсивному отображению всех подкаталогов и файлов.

Таким образом, использование perl -pXe 's/SEARCH/REPLACE/g' -i ** будет рекурсивно замените SEARCH на REPLACE.

Флаг -X указывает perl на "отключить все предупреждения" - это означает, что он не будет жаловаться на каталоги.

Globstar также позволяет делать такие вещи, как sed -i 's/SEARCH/REPLACE/g' **/*.ext, если вы хотите заменить SEARCH на REPLACE во всех дочерних файлах с расширением .ext.

Ответ 9

Вот что я бы сделал:

find /path/to/dir -type f -iname "*filename*" -print0 | xargs -0 sed -i '/searchstring/s/old/new/g'

при этом будут искать все файлы, содержащие filename в имени файла под /path/to/dir, затем для каждого найденного файла найдите строку с searchstring и замените old на new.

Ответ 10

найти и заменить в режиме vi файла Синтаксис выглядит следующим образом: :% S/WORD-To-Find-HERE/Заменить-Word-Здесь/г

ИЛИ :% S/FindMe/ReplaceME/г

Примеры

Подставляемая команда может использоваться в соответствии с вашими требованиями.