Ответ 1
Другой вариант - использовать find, а затем передать его через sed.
find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;
Мне нужно рекурсивно искать указанную строку во всех файлах и подкаталогах в каталоге и заменять эту строку другой строкой.
Я знаю, что команда для его поиска может выглядеть так:
grep 'string_to_find' -r ./*
Но как я могу заменить каждый экземпляр string_to_find
на другую строку?
Другой вариант - использовать find, а затем передать его через sed.
find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;
Я получил ответ.
grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'
Вы могли бы даже последовать за этим.
Пример
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
Это приведет к поиску строки " Windows" во всех файлах относительно текущего каталога и заменит " окна" на linux для каждого вхождения строки в каждом файле.
Это работает лучше всего для меня на OS X:
grep -r -l 'searchtext' . | sort | uniq | xargs perl -e "s/matchtext/replacetext/" -pi
Источник: http://www.praj.com.au/post/23691181208/grep-replace-text-string-in-files
Обычно не с grep, а скорее с sed -i 's/string_to_find/another_string/g'
или perl -i.bak -pe 's/string_to_find/another_string/g'
.
Другие решения сочетают синтаксисы регулярных выражений. Чтобы использовать шаблоны perl/PCRE для и поиска и замены и избежать обработки каждого файла, это работает достаточно хорошо:
grep -rlZP 'match1' | xargs -0r perl -pi -e 's/match2/replace/g;'
где match1
и match2
обычно идентичны, но match1
может быть упрощено для удаления более продвинутых функций, которые имеют отношение только к подстановке, например. группы захвата.
Перевод: grep рекурсивно и список соответствующих файлов, разделенных nul для защиты любых специальных символов в имени файла, которые соответствуют этому шаблону PCRE, а затем связывают эти имена файлов с xargs, которые ожидают нулевой раздел, но не будут делать ничего, если имена не получены, и получить perl для перезаписи каждого файла, заменяя строки, в которых найдены совпадения.
Добавьте параметр I
в grep
, чтобы игнорировать двоичные файлы.
Будьте очень осторожны при использовании 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
Другой вариант - просто использовать 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
.
Вот что я бы сделал:
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
.
найти и заменить в режиме vi файла Синтаксис выглядит следующим образом: :% S/WORD-To-Find-HERE/Заменить-Word-Здесь/г
ИЛИ :% S/FindMe/ReplaceME/г
Примеры
Подставляемая команда может использоваться в соответствии с вашими требованиями.