Самый быстрый способ найти и заменить строку в многочисленных файлах 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' {} + 
  • Bash Как я могу обернуть текст на определенное количество разделенных пространством входов
  • Заменить заполнители в шаблоне
  • Как найти перекрытие двух строк в bash?
  • Как удалить строки, включенные в один файл из другого файла в bash?
  • Найти совпадения из индексного файла без точного соответствия и распечатать последнее поле
  • Двоичный поиск неисправной линии
  • разделить файл на куски, включая больше строк в первой части
  • Разделить файл по шаблону
  • Как я могу использовать Bash для поиска 2 байтов в двоичном файле, увеличения их значений и замены?
  • Интерактивное удаление файлов, перечисленных с помощью путей в текстовом файле
  • Разделить файл на несколько небольших файлов, разделяемых символом новой строки
  • Interesting Posts

    Куда ушли все мои иноды?

    Как узнать общий размер файлов определенного типа на моем жестком диске?

    Fix-клавиши для подсветки клавиатуры

    Как сразу же поставить диск в режим сна (без изменения конфигурации настройки мощности)?

    Печать команды n-го канала в bash

    Отключить раскраску для ls в файловых системах NTFS

    Директива 'StrictModes' не допускается в блоке Match

    Top и ps не показывают тот же результат процессора

    Нет страницы руководства для регулярного выражения в разделе 3 – где это?

    Как обнаружить экран заблокирован или нет, когда экранная заставка активна на Redhat 6.6?

    Запустить сеанс сеанса с более чем 80 столбцами?

    gpg: дешифрование без пароля работает в терминале, но не в msmtp / mutt на основе tmux (невозможно открыть / dev / tty)

    Как искать и заменять двойные символы одиночными символами Unicode в искаженном файле?

    Вызов URL-адреса debian из командной оболочки

    Неизвестный пользователь в postfix (virtualmin)

    Linux и Unix - лучшая ОС в мире.