Linux grep замена текста
Иногда может понадобится найти файл, в котором содержится определённая строка или найти строку в файле, где есть нужное слово. В Linux всё это делается с помощью одной очень простой, но в то же время мощной утилиты grep. С её помощью можно искать не только строки в файлах, но и фильтровать вывод команд, и много чего ещё.
В этой инструкции мы рассмотрим, как выполняется поиск текста в файлах Linux, подробно разберём возможные опции grep, а также приведём несколько примеров работы с этой утилитой.
Что такое grep?
Команда grep (расшифровывается как global regular expression print) - одна из самых востребованных команд в терминале Linux, которая входит в состав проекта GNU. Секрет популярности - её мощь, она даёт возможность пользователям сортировать и фильтровать текст на основе сложных правил.
Утилита grep решает множество задач, в основном она используется для поиска строк, соответствующих строке в тексте или содержимому файлов. Также она может находить по шаблону или регулярным выражениям. Команда в считанные секунды найдёт файл с нужной строчкой, текст в файле или отфильтрует из вывода только пару нужных строк. А теперь давайте рассмотрим, как ей пользоваться.
Синтаксис grep
Синтаксис команды выглядит следующим образом:
$ grep [опции] шаблон [имя файла. ]
$ команда | grep [опции] шаблон
- Опции - это дополнительные параметры, с помощью которых указываются различные настройки поиска и вывода, например количество строк или режим инверсии.
- Шаблон - это любая строка или регулярное выражение, по которому будет вестись поиск
- Файл и команда - это то место, где будет вестись поиск. Как вы увидите дальше, grep позволяет искать в нескольких файлах и даже в каталоге, используя рекурсивный режим.
Возможность фильтровать стандартный вывод пригодится,например, когда нужно выбрать только ошибки из логов или найти PID процесса в многочисленном отчёте утилиты ps.
Опции
Давайте рассмотрим самые основные опции утилиты, которые помогут более эффективно выполнять поиск текста в файлах grep:
Все самые основные опции рассмотрели и даже больше, теперь перейдём к примерам работы команды grep Linux.
Примеры использования
С теорией покончено, теперь перейдём к практике. Рассмотрим несколько основных примеров поиска внутри файлов Linux с помощью grep, которые могут вам понадобиться в повседневной жизни.
Поиск текста в файлах
В первом примере мы будем искать пользователя User в файле паролей Linux. Чтобы выполнить поиск текста grep в файле /etc/passwd введите следующую команду:
grep User /etc/passwd
В результате вы получите что-то вроде этого, если, конечно, существует такой пользователь:
А теперь не будем учитывать регистр во время поиска. Тогда комбинации ABC, abc и Abc с точки зрения программы будут одинаковы:
grep -i "user" /etc/passwd
Вывести несколько строк
Например, мы хотим выбрать все ошибки из лог-файла, но знаем, что в следующей строчке после ошибки может содержаться полезная информация, тогда с помощью grep отобразим несколько строк. Ошибки будем искать в Xorg.log по шаблону "EE":
grep -A4 "EE" /var/log/xorg.0.log
Выведет строку с вхождением и 4 строчки после неё:
grep -B4 "EE" /var/log/xorg.0.log
Выведет целевую строку и 4 строчки до неё:
grep -C2 "EE" /var/log/xorg.0.log
Выведет по две строки с верху и снизу от вхождения.
Регулярные выражения в grep
Регулярные выражения grep - очень мощный инструмент в разы расширяющий возможности поиска текста в файлах. Для активации этого режима используйте опцию -e. Рассмотрим несколько примеров:
grep "^Nov 10" messages.1
Nov 10 01:12:55 gs123 ntpd[2241]: time reset +0.177479 s
Nov 10 01:17:17 gs123 ntpd[2241]: synchronized to LOCAL(0), stratum 10
Поиск в конце строки - спецсимвол "$":
grep "terminating.$" messages
Jul 12 17:01:09 cloneme kernel: Kernel log daemon terminating.
Oct 28 06:29:54 cloneme kernel: Kernel log daemon terminating.
Найдём все строки, которые содержат цифры:
grep "4" /var/log/Xorg.0.log
Вообще, регулярные выражения grep - это очень обширная тема, в этой статье я лишь показал несколько примеров. Как вы увидели, поиск текста в файлах grep становиться ещё эффективнее. Но на полное объяснение этой темы нужна целая статья, поэтому пока пропустим её и пойдем дальше.
Рекурсивное использование grep
grep -r "mydomain.com" /etc/apache2/
В выводе вы получите:
grep -r "zendsite" /etc/apache2/
/etc/apache2/vhosts.d/zendsite_vhost.conf: ServerName zendsite.localhost
/etc/apache2/vhosts.d/zendsite_vhost.conf: DocumentRoot /var/www/localhost/htdocs/zendsite
/etc/apache2/vhosts.d/zendsite_vhost.conf: <Directory /var/www/localhost/htdocs/zendsite>
Здесь перед найденной строкой указано имя файла, в котором она была найдена. Вывод имени файла легко отключить с помощью опции -h:
grep -h -r "zendsite" /etc/apache2/
ServerName zendsite.localhost
DocumentRoot /var/www/localhost/htdocs/zendsite
<Directory /var/www/localhost/htdocs/zendsite>
Поиск слов в grep
Когда вы ищете строку abc, grep будет выводить также kbabc, abc123, aafrabc32 и тому подобные комбинации. Вы можете заставить утилиту искать по содержимому файлов в Linux только те строки, которые выключают искомые слова с помощью опции -w:
grep -w "abc" имя_файла
Поиск двух слов
Можно искать по содержимому файла не одно слово, а два сразу:
egrep -w 'word1|word2' /path/to/file
Количество вхождений строки
Утилита grep может сообщить, сколько раз определённая строка была найдена в каждом файле. Для этого используется опция -c (счетчик):
grep -c 'word' /path/to/file
C помощью опции -n можно выводить номер строки, в которой найдено вхождение, например:
grep -n 'root' /etc/passwd
Инвертированный поиск в grep
Команда grep Linux может быть использована для поиска строк в файле, которые не содержат указанное слово. Например, вывести только те строки, которые не содержат слово пар:
grep -v пар /path/to/file
Вывод имени файла
Вы можете указать grep выводить только имя файла, в котором было найдено заданное слово с помощью опции -l. Например, следующая команда выведет все имена файлов, при поиске по содержимому которых было обнаружено вхождение primary:
grep -l 'primary' *.c
Цветной вывод в grep
Также вы можете заставить программу выделять другим цветом вхождения в выводе:
grep --color root /etc/passwd
Выводы
Вот и всё. Мы рассмотрели использование команды grep для поиска и фильтрации вывода команд в операционной системе Linux. При правильном применении эта утилита станет мощным инструментом в ваших руках. Если у вас остались вопросы, пишите в комментариях!
Мне нужно заменить строку в большом количестве файлов в папке с ssh доступом только к серверу. Как я могу это сделать?
Появления «foo» будут заменены на «bar».
В системах BSD, таких как macOS, вам необходимо предоставить расширение для резервной копии, например -i '.bak' или «риск повреждения или частичное содержимое» для man-страницы.
Это не работает для меня, если в строке есть пробелы или специальные символы. Любая идея, почему это может быть, или мне нужно как-то избежать их? Спасибо! По крайней мере, для моей версии sed , -i требуется строка после нее, которая добавляется к старым именам файлов. Поэтому sed -i .bak 's/foo/bar/g' *.xx перемещает все .xx файлы к эквивалентному .xx.bak имени и затем генерирует .xx файлы с подстановкой foo → bar. @MatthewHerbst, чтобы избежать пробелов, используйте \ like sed -i 's/foo\ with\ spaces/bar/g' * . Я полагаю, вы узнали об этом так долго . но так остаётся другим, которые находят ту же проблему. Для чего-то рекурсивного вы можете попробовать следующее. Обратите внимание, что это не работает, если список файлов огромен. sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)Аналогично ответу Каспара, но с флагом g, чтобы заменить все вхождения в строке.
Для глобального нечувствительного к регистру:
Если вы работаете в OSX и ваши шаблоны могут содержать точки и вы хотите заменить на месте (без файла резервной копии), вы должны использовать LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' <> \; (см. Этот пост и этот ) Это определенно сработало для меня, так как позволяет фильтровать с -name "* .js" ' Подробный вариант был бы классным, но вы можете просто повторить, чтобы увидеть, были ли внесены изменения. Примечание: Для подстановочных знаков попробуйте '-name "* .php"', и grep плохо работает с рекурсией и подстановочными знаками, вы должны добавить --include=*.whatever с -r Не делайте этого из корня проверенного репозитория Git. Вы можете случайно повредить его базу данных в .git/ . Обязательно cd опускайтесь на более низкий уровень. Я только что сделал это в моем мерзавца репо и теперь git status возвращается: error: bad index file sha1 signature. fatal: index file corrupt . Что дает?Ответ @ kev хорош, но влияет только на файлы в ближайшем каталоге. В приведенном ниже примере используется grep для рекурсивного поиска файлов. Это работает для меня каждый раз.
Grep -r : --recursive , рекурсивно прочитать все файлы в каждом каталоге.
grep -l : --print-with-match , печатает имя каждого файла, у которого есть совпадение, вместо печати совпадающих строк.
grep -i : --ignore-case .
xargs : преобразовать STDIN в аргументы, следуйте этому ответу .
Команда xargs -i @
, знак @ - это заполнитель, который может быть заменен любой строкой.
sed -i : редактировать файлы на месте, без резервных копий.
СЭД с / регулярное выражение / замена / : заменой строки сопоставления регулярное выражение с заменой .
sed s / regexp / replace / g : global , делать замену для каждого совпадения вместо только первого совпадения.
Это сработало для меня:
Но это не так sed -i 's/string1/string2/g' * . Может быть, «foo» не был строкой1, а «bar» - не строкой2.
Об использовании OSX: find ./ -type f -exec sed -i '' -e 's/string1/string2/' <> \;Для наиболее быстрого использования команда rpl гораздо проще запомнить. Вот замена (foo -> bar), рекурсивно для всех файлов:
Вам, вероятно, понадобится установить его ( apt-get install rpl или аналогичный).
Однако для более сложных заданий, которые включают регулярные выражения и обратную подстановку или переименование файлов, а также поиск и замену, наиболее общий и мощный инструмент, о котором я знаю, это repren , небольшой скрипт на Python, который я написал некоторое время назад для некоторых более сложные задачи переименования и рефакторинга. Причины, по которым вы можете предпочесть это:
- Поддержка переименования файлов, а также поиск и замена содержимого файла.
- Просмотрите изменения, прежде чем совершать поиск и замену.
- Поддержка регулярных выражений с обратной подстановкой, целыми словами, без учета регистра и с сохранением регистра (замените режимы foo -> bar, Foo -> Bar, FOO -> BAR).
- Работает с множественными заменами, включая перестановки (foo -> bar и bar -> foo) или наборы неуникальных замен (foo -> bar, f -> x).
Чтобы использовать это pip install repren . Проверьте README для примеров.
Вау, репрен отлично! Просто использовал его, чтобы изменить часть слова в именах классов, методах и переменных, переименовывая файлы, чтобы они соответствовали более чем 1000+ заголовочных и исходных файлов C ++, и с первого раза он отлично работал с одной командой. Спасибо!Чтобы заменить строку в нескольких файлах, вы можете использовать:
Чтобы заменить путь в файлах (избегая escape-символов), вы можете использовать следующую команду:
Знак @ означает, что все специальные символы должны игнорироваться в следующей строке.
Именно то, что я искал во всех других ответах. А именно, как обращаться со специальными символами, например, при изменении строки, которая является путем. Спасибо. Похоже, большой упущение в других ответах.Если в вашей строке есть косая черта (/), вы можете изменить разделитель на «+».
Эта команда будет выполняться рекурсивно в текущем каталоге.
Первая строка вхождения «foo» будет заменена на «bar». И вы можете использовать вторую строку для проверки.
Почему вы ссылаетесь на свой блог? Он содержит точно такой же текст, как и ваш ответ.Если у вас есть список файлов, которые вы можете использовать
Если у вас есть все файлы, которые вы можете использовать
Если у вас есть список файлов с расширением, вы можете использовать
на самом деле, "--file" должен быть просто "-", по крайней мере, в моей версии Хотя я хотел бы по достоинству оценить решение, которое работает без использования кавычек в качестве регулярного выражения. Это работает нормально - и если вы хотите заменить все строки в нескольких файлах, которые заканчиваются, например, на «.txt», вы можете просто сделать replace "old_string" "new_string" -- *.txt Лучше добавить откуда взять эту replace утилиту. Без этой информации этот ответ неполон.«Вы также можете использовать find и sed, но я обнаружил, что эта маленькая строчка perl прекрасно работает.
- -e означает выполнить следующую строку кода.
- -i означает редактировать на месте
- -пишем предупреждения
- петля
Мои лучшие результаты получены от использования Perl и grep (чтобы убедиться, что файл имеет выражение поиска)
Если вы хотите найти строку search и заменить ее replace в нескольких файлах, это моя проверенная в бою формула в одну строку :
Быстрое объяснение grep:
- -R - рекурсивный поиск
- -i - без учета регистра
- -I пропустить двоичные файлы (вы хотите текст, верно?)
- -l - распечатать простой список в качестве вывода. Необходим для других команд
Затем вывод grep передается в sed (через xargs), который фактически используется для замены текста. -i Флаг будет изменять файл напрямую. Снимите его для своего рода «пробного запуска».
Я придумал собственное решение, прежде чем нашел этот вопрос (и ответы). Я искал различные комбинации «заменить», «несколько» и «xml», потому что это было мое приложение, но не нашел именно этого.
Моя проблема: у меня были весенние xml-файлы с данными для тестовых случаев, содержащие сложные объекты. Рефакторинг исходного кода java изменил много классов и не применим к файлам данных xml. Чтобы сохранить данные тестовых случаев, мне нужно было изменить все имена классов во всех XML-файлах, распределенных по нескольким каталогам. Все это при сохранении резервных копий оригинальных XML-файлов (хотя это не было обязательным, так как контроль версий спас бы меня здесь).
Я искал некоторую комбинацию find + sed , потому что она работала для меня в других ситуациях, но не с несколькими заменами одновременно.
Затем я нашел ответ на запрос ubuntu, и он помог мне построить мою командную строку:
И это сработало отлично (ну, в моем случае было шесть разных замен). Но учтите, что он затронет все файлы * .xml в текущем каталоге. Из-за этого, и если вы подотчетны системе контроля версий, вы можете сначала фильтровать и передавать только sed тем, у кого действительно есть нужные вам строки; подобно:
а для windows я только что узнал, что есть способ найти строку - пока не проверял, как ее заменить - одной командой: findstr /spin /c:"quéquieresbuscar" *.xml это будет удобно.Действительно хромая, но я не мог заставить любую из команд sed работать правильно на OSX, поэтому вместо этого я сделал эту глупую вещь:
^ - скопируйте эти три строки в мой буфер обмена (да, включите завершающий перевод строки), затем:
Тупой . Hacky . эффективный .
-e просто говорит sed, что следующий токен - это команда. Для расширенных регулярных выражений используйте -E вместо этого.-i '' убедитесь, что вы не делаете никаких резервных копий.
-e для современного регулярного выражения.
Редактор потока изменяет несколько файлов «на месте» при вызове с -i коммутатором, который принимает в качестве аргумента файл резервной копии, заканчивающийся аргументом. Так
заменяет foo на bar во всех файлах в этой папке, но не спускается в подпапки. Это, однако, сгенерирует новый .bak файл для каждого файла в вашем каталоге. Чтобы сделать это рекурсивно для всех файлов в этом каталоге и всех его подкаталогах, вам нужен помощник, например find , для обхода дерева каталогов.
find позволяет вам дополнительно ограничивать, какие файлы изменять, указав дополнительные аргументы, например find ./ -name '*.php' -or -name '*.html' -print0 , при необходимости.
Примечание: GNU sed не требует окончания файла, также sed -i 's/foo/bar/g' * будет работать; FreeBSD sed требует расширения, но допускает пробел между ними, так что sed -i .bak s/foo/bar/g * работает.
скрипт для мультиредактной команды
Из ответа Каспара я сделал скрипт bash, чтобы принимать аргументы командной строки и, необязательно, ограничивать имена файлов, соответствующие шаблону. Сохраните в вашем $ PATH и сделайте исполняемый файл, затем просто используйте команду выше.
Если файл содержит обратную косую черту (обычно пути), вы можете попробовать что-то вроде этого:
Чтобы сохранить свой личный английский узел, я написал служебный скрипт, который помогает рекурсивно заменить несколько пар старой / новой строки для всех файлов в каталоге.
Несколько пар старой / новой строки управляются в хэш-карте.
Dir может быть установлен через командную строку или переменную окружения, карта жестко запрограммирована в скрипте, но вы можете изменить код для загрузки из файла, если это необходимо.
Требуется Bash 4.2, из-за некоторых новых функций.
en_standardize.sh:
Использование команды ack будет намного быстрее:
Также, если у вас есть пробел в результатах поиска. Вы должны избежать этого.
Я привожу пример для исправления распространенной ошибки shebang в источниках Python.
Вы можете попробовать подход grep / sed. Вот тот, который работает с GNU sed и не сломает git-репо:
Или вы можете использовать greptile :)
Я только что проверил первый скрипт, и второй тоже должен работать. Будьте осторожны с escape-символами, я думаю, что в большинстве случаев проще использовать greptile. Конечно, вы можете делать много интересных вещей с помощью sed, и для этого предпочтительнее освоить его с помощью xargs.
Я нашел это из другого поста (не помню, какой именно), и хотя он не самый элегантный, он прост и, как начинающий пользователь Linux, не доставил мне никаких проблем.
если у вас есть пробелы или другие специальные символы, используйте \
для строк в подкаталогах используйте **
Команда ниже может быть использована для поиска файлов и замены файлов:
Существует более простой способ с использованием простого файла сценария:
откройте файл в gedit или редакторе по вашему выбору, я использую gedit здесь.
Затем в редакторе вставьте следующее в файл
Сохраните файл, закройте gedit , затем выйдите из терминала или просто закройте его и затем запустите, чтобы иметь возможность загрузить новый скрипт, который вы добавили.
Перейдите в каталог, где у вас есть несколько файлов, которые вы хотите редактировать. Затем запустите:
Нажмите ввод, и это автоматически заменит oldstring и oldstring1 во всех файлах, которые их содержат, на правильные newstring и newstring1 соответственно.
Он пропустит все каталоги и файлы, которые не содержат старых строк.
Это может помочь в устранении утомительной работы при наборе текста, если у вас есть несколько каталогов с файлами, которые требуют замены строки. Все, что вам нужно сделать, это перейти к каждому из этих каталогов, а затем выполнить:
Все, что вам нужно сделать, это убедиться, что вы включили или добавили все строки замены, как я показал вам выше:
replace "oldstring" "newstring" -- *
в конце файла / bin / replace_string_files_present_dir .
Чтобы добавить новую строку замены, просто откройте созданный нами скрипт, набрав в терминале следующее:
sudo gedit /bin/replace_string_files_present_dir
Не беспокойтесь о количестве строк замены, которые вы добавляете, они не будут действовать, если старая строка не найдена.
web программирование, администрирование и всякая всячина, которая может оказаться полезной
Поиск текста по файлам в Linux:
Поиск и удаление файлов, содержащих строку
78.46.14.162
find /var/named/ -type f -exec grep "MX" <> ; -print | grep named
(имя файла и найденный текст)
find . -name '*.*htm*' -exec grep -i iframe <> ; -print | less
ищем iframe (файлы, перезаписанные вирусом).
Массовый поиск и замена в файлах:
"s/search text/replace text/g" index.php
i
- флаг, указывающий на то, что оригинальный файл будет сохранен как file.ext
g - заменяем не только первое вхождение
поиск и замена в нескольких файлах с использованием perl
perl -pi
-e 's/foo/bar/' [files]
Поиск и замена с использованием sed (ищем скрипт и заменяем его на комментарий. Экранируем восклицательный знак:
sed -i.
"s/≶script>var k;.*script>/≶\!-- deleted -->/g" index.php
Флаг -i (inplace) означает, что результат следует сделать в файле. При наличии символов после -i резервная копия сохраняется в соответствующий файл (некоторые системы не дают выполнить команду с флагом -i без сохранения резервной копии).
Для удобства дальнейшего удаления использую -i.
(можно -i.bak - сохранит файлы, добавляя расширение bak). Дальнейшее удаление при помощи команды find + delete
find ./ -name '*.
Пригодилось при замене вирусных кодов на сайте - первым этапом поиск файлов, затем - дальнейшая замена. В принципе, можно сделать всё одним махом. В случае замены флаг -i
Просмотр файла, начиная со строки 532
more +532 file.txt
Поиск файлов по размеру
Для удаления файлов, найденных командой find достаточно указать дополнительный параметр -delete
Поиск php файлов размером 535 байт (c - указывает на размер в байтах, по умолчанию - в блоках 512)
find ./ -type f -name '*.php' -size 599c
При указании размера со знаком плюс или минус - происходит поиск файлов соответственно больше или меньше указанного значения.
Поиск подстроки в недавно модифицированных файлах (40 дней назад ! минус перед числом обязателен):
find ./ -name "*.php" -mtime -40 -exec grep "breadcrumb" <> \;
Поиск файлов find + последующий grep для них (find + exec grep).. во второй строчке - ещё и удаление
find ./ -type f -name '*.php' -size 599c -exec grep -l "c1120ba44a14664ed80cfa5a18832c1b9b39dec0" <> \;
find ./ -type f -size 599c -exec grep -l "c1120ba44a14664ed80cfa5a18832c1b9b39dec0" <> \; -delete
Поиск файлов больше мегабайта (+1M) меньше (-1M)
find ./ -type f -size +1M
Поиск файлов с нулевой длиной
find ./ -type f -size 0
Поиск и удаление файлов с нулевой длиной (вторым парамтером - путь к каталогу.. ./ означает текущий
find ./ -type f -size 0 -delete
Поиск номеров строк в файле (чтобы grep вывел номер строки - используем с параметром -n)
Чтобы вытащить определённые строки из файла (или удалить строки в начале файла и в конце файла), можно использовать sed - выведет строки с 4 по 17
sed -n '3,10p' file.txt
Переместить файлы размером >2Mb в каталог /tmp (и вообще выполнить любую команду с файлами)
find ./ -size +2M -exec cp <> /tmp \;
Ресайз всех изображений в каталоге, размер которых превышает 2М
find ./ -size +2M -exec convert <> -resize 1200x1200 <> \;
Ресайз всех изображений, по маске
find ./ -name '493_*' -exec convert <> -resize 1200x1200 <> \;
Рекурсивно удалить все .svn директории в подкаталогах
find . -name ".svn" -exec rm -rf <> \;
Метки: linux
Автор будет признателен, если Вы поделитесь ссылкой на статью, которая Вам помогла:
BB-код (для вставки на форум)
html-код (для вставки в ЖЖ, WP, blogger и на страницы сайта)
ссылка (для отправки по почте)
Мне нужно рекурсивно искать указанную строку во всех файлах и подкаталогах в каталоге и заменять эту строку другой строкой.
Я знаю, что команда для его поиска может выглядеть так:
Но как я могу заменить каждый экземпляр string_to_find на другую строку?
Другой вариант - использовать find, а затем передать его через sed.
Я получил ответ.
Вы могли бы даже последовать за этим.
Пример
Это приведет к поиску строки " Windows" во всех файлах относительно текущего каталога и заменит " окна" на linux для каждого вхождения строки в каждом файле.
Это работает лучше всего для меня на OS X:
Обычно не с grep, а скорее с sed -i 's/string_to_find/another_string/g' или perl -i.bak -pe 's/string_to_find/another_string/g' .
Другие решения сочетают синтаксисы регулярных выражений. Чтобы использовать шаблоны perl/PCRE для и поиска и замены и избежать обработки каждого файла, это работает достаточно хорошо:
где match1 и match2 обычно идентичны, но match1 может быть упрощено для удаления более продвинутых функций, которые имеют отношение только к подстановке, например. группы захвата.
Перевод: grep рекурсивно и список соответствующих файлов, разделенных nul для защиты любых специальных символов в имени файла, которые соответствуют этому шаблону PCRE, а затем связывают эти имена файлов с xargs, которые ожидают нулевой раздел, но не будут делать ничего, если имена не получены, и получить perl для перезаписи каждого файла, заменяя строки, в которых найдены совпадения.
Добавьте параметр I в grep , чтобы игнорировать двоичные файлы.
Будьте очень осторожны при использовании find и sed в git-репо! Если вы не исключите двоичные файлы, вы можете получить следующую ошибку:
Чтобы устранить эту ошибку, вам нужно вернуть sed , заменив new_string на old_string . Это вернет замененные строки, поэтому вы вернетесь к началу проблемы.
Правильный способ поиска и замены строки - пропустить find и использовать вместо него grep , чтобы игнорировать двоичные файлы:
Кредиты для @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 .
Читайте также: