Найти и заменить HTML-код для нескольких файлов в нескольких каталогах - PullRequest
2 голосов
/ 03 июня 2011

Я очень хорошо разбираюсь в сценариях оболочки, но для того, чтобы сделать это, нужны более сложные команды.

Для одной задачи мне нужно найти и заменить HTML-код в файлах index.html на моем сервере.Эти файлы находятся в нескольких каталогах с согласованным соглашением об именах.([буква] [трехзначное число]) См. пример ниже.

files: index.html
path: /www/mysite/board/today/[rsh][0-9]/ 
string to find: (div id="id")[code](/div)<--#include="(path)"-->(div id="id")[more code](/div)
string to replace with: (div id="id")<--include="(path)"-->(/div)

Надеюсь, вы не возражаете против псевдо-регулярного выражения.Папки, содержащие мои целевые файлы index.html, похожи на r099, s017, h123.И достаточно сказать, что HTML-код, который я пытаюсь заменить, является относительно длинным, но все же это всего лишь строка.

Второе задание аналогично первому, меняются только имена файлов.

files: [rsh][0-9].html
path: www/mysite/person/[0-9]/[0-9]/[0-9]/card/2011/
string: (div id="id")[code](/div)<--include="(path)"-->(div id="id")[more code](/div)
string to replace with: (div id="id")<--include="(path)"-->(/div)

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

Любая помощь будет принята с благодарностью.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 03 июня 2011

У вас есть три отдельных подзадачи:

  1. замена текста в файле
  2. справка со спецсимволами
  3. выбор файлов для применения преобразования к

1. Инструмент для замены канонического текста: sed:

sed -e 's/PATTERN/REPLACEMENT/g' <INPUT_FILE >OUTPUT_FILE

Если у вас есть GNU sed (например, в Linux или Cygwin), передайте -i, чтобы преобразовать файл на месте. Вы можете использовать несколько файлов в одной командной строке.

sed -i -e 's/PATTERN/REPLACEMENT/g' FILE OTHER_FILE…

Если у вашего sed нет опции -i, вам нужно записать в другой файл и впоследствии переместить его на место. (Это то, что GNU sed делает за кулисами.)

sed -e 's/PATTERN/REPLACEMENT/g' <FILE >FILE.tmp
mv FILE.tmp FILE

2. Если вы хотите заменить буквенную строку литеральной строкой, вам необходимо поставить перед всеми специальными символами обратную косую черту. Для шаблонов sed специальные символы .\[^$* плюс разделитель для команды s (обычно /). Для замены текста в тексте используются специальные символы \& и символы новой строки. Вы можете использовать sed, чтобы превратить строку в подходящий шаблон или текст для замены.

pattern=$(printf %s "$string_to_replace" | sed -e 's![.\[^$*/]!\\&!g')
replacement=$(printf %s "$replacement_string" | sed -e 's![\&]!\\&!g')

3. Чтобы воздействовать на несколько файлов непосредственно в одной или нескольких директориях, используйте подстановочные знаки оболочки. Ваши требования не кажутся полностью совместимыми; Я думаю, что это шаблоны, которые вы ищете, но обязательно просмотрите их.

/www/mysite/board/today/[rsh][0-9][0-9][0-9]/index.html
/www/mysite/person/[0-9]/[0-9]/[0-9]/card/2011/[rsh][0-9].html

Это будет соответствовать файлам типа /www/mysite/board/today/r012/index.html и /www/mysite/person/4/5/6/card/2011/h7.html, но не /www/mysite/board/today/subdir/s012/index.html или /www/mysite/board/today/r1234/index.html.

Если вам нужно рекурсивно воздействовать на файлы в подкаталогах, используйте find. Это не соответствует вашим требованиям, и этот ответ уже достаточно длинный, поэтому я остановлюсь здесь.

4. Собираем все вместе:

string_to_replace='(div id="id")[code](/div)<--#include="(path)"-->(div id="id")[more code](/div)'
replacement_string='(div id="id")<--include="(path)"-->(/div)'
pattern=$(printf %s "$string_to_replace" | sed -e 's![.\[^$*/]!\\&!g')
replacement=$(printf %s "$replacement_string" | sed -e 's![\&]!\\&!g')
sed -i -e "s/$pattern/$replacement/g" \
  /www/mysite/board/today/[rsh][0-9][0-9][0-9]/index.html \
  /www/mysite/person/[0-9]/[0-9]/[0-9]/card/2011/[rsh][0-9].html

Последнее замечание: вы, кажется, работаете над HTML с помощью регулярных выражений. Это часто не очень хорошая идея .

0 голосов
/ 03 июня 2011

Поиск файлов можно легко выполнить с помощью find -regex:

find www/mysite/board/today -regex ".*[rsh][0-9][0-9][0-9]/index.html"
find www/mysite/person -regex ".*[0-9]/[0-9]/[0-9]/card/2011/[rsh][0-9][0-9][0-9].html"

Из-за особенностей HTML замена содержимого может быть не очень простой с sed, поэтому я бы предложил использовать HTMLили библиотека XML-анализа в Perl-скрипте.Можете ли вы предоставить краткий образец фактического HTML-файла и результат замены?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...