Самый быстрый способ найти и заменить строку в многочисленных файлах HTML

У меня есть многочисленные HTML-файлы, все вложенные в разные папки, содержащиеся в одной общей папке. В каждом из этих HTML-файлов мне нужно заменить

/contact/index.html 

С

 /contact/index.php 

Есть ли простой способ сделать это из командной строки?

2 Solutions collect form web for “Самый быстрый способ найти и заменить строку в многочисленных файлах HTML”

Если у вас есть GNU find и GNU sed , попробуйте это в родительской папке:

 find . -type f \( -iname "*.htm" -o -iname "*.html" \) -exec sed -i.bak 's#/contact/index\.html#/contact/index.php#' '{}' + 

Это найдет все файлы, чье имя заканчивается на .html или .HTML или .htm или .HTM (или .HtM …) и запускает на них команду sed :

 sed -i.bak 's#/contact/index\.html#/contact/index.php#g' 

Это сделает foo.htm вам замену и создаст резервную копию исходного foo.htm именем foo.htm.bak . Если вам не нужны резервные копии, просто удалите .bak .


ДЕТАЛИ:

Команда find , очевидно, находит файлы или папки. Синтаксис может быть довольно сложным и подробно объясняется на его man page руководства, некоторые из которых воспроизводятся ниже:

Общий формат – это find [where] [what] . В приведенном выше примере, where находится . что означает текущий каталог. Все файлы, имеющие html или подобное расширение, поэтому я использую iname который:

  -iname pattern Like -name, but the match is case insensitive. For example, the patterns `fo*' and `F??' match the file names `Foo', `FOO', `foo', `fOo', etc. 

Тем не менее, я хочу, чтобы он соответствовал как html и htm поэтому я использую флаг -o что означает:

  expr1 -o expr2 Or; expr2 is not evaluated if expr1 is true. 

Такие конструкции должны быть сгруппированы вместе, что делается скобками ( ) которые, однако, должны быть экранированы из оболочки, поэтому мы используем \( и \) .

Магия происходит в -exec :

  -exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in argu‐ ments where it is alone, as in some versions of find. [...] The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead. 

Другими словами, если задана команда -exec ls {} , find найдет все файлы, соответствующие условиям, которые вы установили, и повторите их, заменив {} на текущее имя файла и выполнив указанную команду. Я также использую + вместо \; для завершения вызова exec потому что это заставит find попробовать и запустить как можно меньше команд, это просто небольшая оптимизация, если у вас нет тысяч файлов, когда это может быть важно:

  -exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total num‐ ber of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the com‐ mand. The command is executed in the starting directory. 

Наконец, sed – это текстовый текстовый редактор командной строки, он будет применять команду, которую вы передаете в каждую строку файла. В этом случае команда является заменой, основной формат:

 s#pattern#replacement#flags 

Разделители ( # ) могут быть любым специальным символом и традиционно / но я выбрал # потому что иначе мне пришлось бы избежать / . Обратите внимание, что ChrisDown в своем ответе решил использовать | , Это просто личный выбор, и они эквивалентны.

Предполагая, что у вас есть GNU sed :

 find -iname '*.html' -type f -exec sed -i 's|/contact/index\.html|/contact/index.php|g' {} + 
  • loop для вставки определенных файлов в разные каталоги
  • Поиск и сортировка журналов ошибок на основе определенной строки
  • Замена места для команды paste
  • bash - заменить пространство новой строкой
  • Умножение чисел на месте в файле
  • Преобразование базиса BASH из десятичного в шестнадцатеричное
  • Отступ, как первая строка
  • Bash - файл, массивы и выходные данные
  • Извлечь начальные и конечные координаты в соответствии с определенной длиной нефиксированного интервала
  • Как форматировать потоковый вывод JSON из Node.js?
  • Как суммировать числа внутри многих 2D-массивов
  • Linux и Unix - лучшая ОС в мире.