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

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

3
01.09.2013, 20:59
2 ответа

Да, если у Вас есть 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.bak. Если Вы не хотите резервные копии, просто удалите .bak.


Подробнее:

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

Общий формат find [where] [what]. В примере я дал выше, where . что означает текущий каталог. what все файлы, которые имеют a 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 в его ответе принял решение использовать |. Это - просто личный выбор, и эти два эквивалентны.

5
27.01.2020, 21:11
  • 1
    Звуки, хорошие, я попробую его через секунду. Я мог быть грубым и попросить повреждение вниз каждого бита команды, которую Вы представили? Я очень предпочитаю учиться, чем копия и вставка.Спасибо. уверенный –  Ben 01.09.2013, 21:36
  • 2
    @Ben, взгляните на обновленный ответ. –  terdon♦ 01.09.2013, 21:50
  • 3
    Красивый я прочитаю его теперь, спасибо. –  Ben 01.09.2013, 21:58

Предположение, что у Вас есть GNU sed:

find -iname '*.html' -type f -exec sed -i 's|/contact/index\.html|/contact/index.php|g' {} +
3
27.01.2020, 21:11
  • 1
    Oy! Вы отредактировали мой, в то время как я делал точно то же исправление (выходящий '.', как Вы очень правильно сделали в своем ответе), :) –  terdon♦ 01.09.2013, 21:16
  • 2
    @terdon Извините! Вы предпочли бы, чтобы я оставил комментарий вместо этого в будущем? Я никогда не уверен, каков этикет только с редактированием или выяснением вместо этого, но Вы, казалось, ценили его прежде, таким образом, я не знаю. –  Chris Down 01.09.2013, 21:16
  • 3
    О боже не отредактируйте и исправьте любой ценой! Это было просто забавно, что я заметил, что Вы сделали это, думал, что это было хорошей идеей и собиралось исправить его, и Вы побеждаете меня к нему. Это не беспокоило меня ни в малейшей степени, наоборот я ценю его. –  terdon♦ 01.09.2013, 21:17
  • 4
    @ChrisDown - да всегда редактируют что-либо, что я пишу также. Когда я спросил Gilles & Stephane, они сказали то же. Большинство постоянных клиентов соглашается с редактированием. Некоторые более новые люди, кажется, пугаются его, я обычно объясняю им, что они могут всегда возвращаться, что они не любят 8-). –  slm♦ 01.09.2013, 22:11
  • 5
    @slm Stephane всегда редактирует мой, когда я забываю -- (т.е. каждый раз, по некоторым причинам, даже при том, что это - вещь, которую я всегда говорю людям делать...). Также не стесняйтесь редактировать мой. –  Chris Down 01.09.2013, 22:24

Теги

Похожие вопросы