Linux grep замена текста

Обновлено: 08.07.2024

Иногда может понадобится найти файл, в котором содержится определённая строка или найти строку в файле, где есть нужное слово. В 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 , делать замену для каждого совпадения вместо только первого совпадения.

это не сработало для меня, но это сработало: grep --include= -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @ @pymarco Можете ли вы объяснить эту команду? Я не знаю, почему вам пришлось использовать xargs вместо использования sed после | , также, почему -i в команде xargs? Я прочитал в руководстве это устарело и должен использовать -I вместо этого. И @ используется как разделитель для начала и конца для шаблона? На OSX это нормально: grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @ Было бы неплохо, если бы вы отказались от некоторых опций ( rli ) и @ знака, например

Это сработало для меня:

Но это не так 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 . эффективный .

-i '' убедитесь, что вы не делаете никаких резервных копий.

-e для современного регулярного выражения.

-e просто говорит sed, что следующий токен - это команда. Для расширенных регулярных выражений используйте -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 .

Читайте также: