Мне нужно рекурсивно искать указанную строку во всех файлах и подкаталогах в каталоге и заменить эту строку другой строкой.
Я знаю, что команда найти его может выглядеть так:
grep 'string_to_find' -r ./*
Но как я могу заменить каждый экземпляр string_to_find
другой строкой?
sed -i 's/.*substring.*/replace/'
sed -i 's/\(.*\)substring\(.*\)/\1replace\2/'
Ответы:
Другой вариант - использовать find, а затем передать его через sed.
источник
-i
. Например,find /path/to/files -type f -exec sed -i "" "s/oldstring/new string/g" {} \;
Во всяком случае, предоставление пустой строки по-прежнему создает файл резервной копии в отличие от описанного в руководстве ...-i ""
для OS X. Это работает иначе.CRLF
вLF
Windows.Я получил ответ.
источник
grep
а затем снова сsed
. Использованиеfind
метода более эффективно, но упомянутый метод работает.sed -i 's/str1/str2/g'
чтобыsed -i "" 's/str1/str2/g'
для этого к работе.grep
просматривает все файлы иsed
просматривает только файлы, соответствующие которымgrep
. При использованииfind
метода из другого ответаfind
сначала перечисляются все файлы, а затемsed
выполняется сканирование всех файлов в этом каталоге. Таким образом, этот метод не обязательно медленнее, он зависит от количества совпадений и различий в скоростях поиска междуsed
,grep
иfind
.Вы могли бы даже сделать это так:
пример
Это будет искать строку « windows » во всех файлах относительно текущего каталога и заменять « windows » на « linux » для каждого вхождения строки в каждом файле.
источник
grep
полезно, только если есть файлы, которые не должны быть изменены. Запускsed
всех файлов обновит дату изменения файла, но оставит содержимое без изменений, если совпадений нет.-i
Я полагаю, что при использованииsed
изменяется время файла каждого файла, к которому он прикасается, даже если содержимое остается неизменным.sed
также преобразует окончания строк Я не используюsed
на Windows вCRLF
LF
Это работает лучше всего для меня на OS X:
Источник: http://www.praj.com.au/post/23691181208/grep-replace-text-string-in-files
источник
ag "search" -l -r . | sort | uniq | xargs perl -e 's/search/replace' -pi
sort -u
четная часть этого? При каких обстоятельствах вы ожидаетеgrep -rl
получить одно и то же имя файла дважды?Другие решения смешивают синтаксис регулярных выражений. Для того, чтобы использовать Perl / шаблоны PCRE для обоих поиска и замены, а только процесс согласования файлов, это работает очень хорошо:
где
match1
иmatch2
обычно идентичны, ноmatch1
могут быть упрощены, чтобы удалить более продвинутые функции, которые имеют отношение только к замене, например, захват групп.Перевод:
grep
рекурсивно и список файлов, которые соответствуют этому шаблону PCRE, разделенные nul для защиты любых специальных символов в имени файла, затем передают те имена файлов, кxargs
которым ожидает разделенный нулями список, но ничего не сделают, если не будут получены имена, и получитьperl
замену строк, где найдены совпадения.Добавьте
I
переключатель,grep
чтобы игнорировать двоичные файлы. Для сопоставления с учетом регистра удалитеi
переключатель изgrep
иi
флаг, прикрепленный к выражению подстановки, но не самi
переключательperl
.источник
find2perl
который поставляется с Perl, который делает подобные вещи без каких-либоxargs
хитростей.find
не ищет содержимое файла, и смысл состоит в том, чтобы обрабатывать только совпадающие файлы без написания Perl-программы.Обычно не с grep, а с
sed -i 's/string_to_find/another_string/g'
илиperl -i.bak -pe 's/string_to_find/another_string/g'
.источник
Будьте очень осторожны при использовании
find
иsed
в git-репо! Если вы не исключите двоичные файлы, вы можете получить следующую ошибку:Чтобы устранить эту ошибку, вам нужно отменить
sed
, заменивnew_string
на вашold_string
. Это вернет замененные строки, поэтому вы вернетесь к началу проблемы.Правильный способ поиска и замены строки - вместо этого пропустить
find
и использоватьgrep
, чтобы игнорировать двоичные файлы:Кредиты для @hobs
источник
Вот что я бы сделал:
он будет искать все файлы, содержащиеся
filename
в имени файла под/path/to/dir
, чем для каждого найденного файла, искать строку сsearchstring
и заменятьold
наnew
.Хотя, если вы хотите не искать конкретный файл со
filename
строкой в имени файла, просто сделайте:Это будет делать то же самое выше, но со всеми файлами, найденными в
/path/to/dir
.источник
Другой вариант - просто использовать Perl с Globstar.
Включение
shopt -s globstar
в вашем.bashrc
(или где бы то ни было) позволяет**
шаблону glob рекурсивно сопоставлять все подкаталоги и файлы.Таким образом, использование
perl -pXe 's/SEARCH/REPLACE/g' -i **
будет рекурсивно замененоSEARCH
наREPLACE
.-X
Флаг говорит Perl , чтобы «отключить все предупреждения» - это означает , что он не будет жаловаться на каталоги.Globstar также позволяет делать такие вещи , как ,
sed -i 's/SEARCH/REPLACE/g' **/*.ext
если вы хотите заменитьSEARCH
сREPLACE
во всех дочерних файлах с расширением.ext
.источник
grep
иsed
.