Задать вопрос

Массовая замена в файлах. Регулярки или скрипт?

Добрый день. Нужна помощь в решении следующей задачи.
Пример.
Дано:
<head>
<title>Руководство</title>
</head>
<body>
<h1>Мерседес. Рулевое управление</h1>
<p>Текст</p>
</body>
</html>

Требуется:
<head>
<title>Руководство Мерседес. Рулевое управление (сделать тайтл+h1)</title>
</head>
<body>
<h1>Мерседес. Рулевое управление</h1>
<p>Текст</p>
</body>
</html>

Сделать заменой в файлах (не на лету, не подменой скриптом и тд). Файлов около 50 000, тайтл везде одинаковый, h1 разный.
Какие есть варианты?
Спасибо
  • Вопрос задан
  • 159 просмотров
Подписаться 1 Простой 10 комментариев
Решения вопроса 1
RAX7
@RAX7
replace-title.js

// replace-title.js
const fs = require('fs');
const path = require('path');
const { default: render } = require('dom-serializer');
const htmlparser2 = require('htmlparser2');
const { findOne, textContent } = htmlparser2.DomUtils;

const isTargetFile = (filePath) => /\.html/i.test(filePath);

const srcDir = path.resolve(__dirname, process.argv[2]);
const dstDir = path.resolve(__dirname, process.argv[3]);

function processFile(srcFilePath, dstFilePath) {
  const inHtmlString = fs.readFileSync(srcFilePath, { encoding: 'utf8' });
  const dom = htmlparser2.parseDocument(inHtmlString);

  const titleElement = findOne((node) => node.type === 'tag' && node.name === 'title', dom.childNodes, true);
  const h1Element = findOne((node) => node.type === 'tag' && node.name === 'h1', dom.childNodes, true);

  if (titleElement) {
    const titleText = textContent(titleElement).trim();
    const h1Text = h1Element ? textContent(h1Element).trim() : '';

    const titleTextNode = titleElement.childNodes[0];

    if (titleTextNode) {
      titleTextNode.data = h1Text ? `${titleText} | ${h1Text}` : titleText;
    }

    const outHtmlString = render(dom, { encodeEntities: 'utf8' });
    fs.writeFileSync(dstFilePath, outHtmlString);
  }
}

function processDir(dirPath) {
  const files = fs.readdirSync(dirPath);

  for (const file of files) {
    const absFilePath = path.join(dirPath, file);

    if (fs.statSync(absFilePath).isDirectory()) {
      processDir(absFilePath);
    } else if (isTargetFile(absFilePath)) {
      const relPath = path.relative(srcDir, absFilePath);
      const dstFilePath = path.join(dstDir, relPath);

      const targetDir = path.dirname(dstFilePath);

      if (!fs.existsSync(targetDir)) {
        fs.mkdirSync(targetDir, { recursive: true });
      }

      processFile(absFilePath, dstFilePath);
    }
  }
}
processDir(srcDir);


package.json

{
  "name": "replace-title",
  "version": "1.0.0",
  "description": "",
  "main": "replace-title.js",
  "license": "ISC",
  "dependencies": {
    "dom-serializer": "^2.0.0",
    "htmlparser2": "^8.0.1"
  }
}


Проще скриптом
npm install
node ./replace-title.js ./src ./dst

сконвертирует все html файлы в папке ./src и положит в папку ./dst
перед запуском желательно сделать бэкап
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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