用 nodejs 替换文件中的字符串

IT技术 javascript node.js replace gruntjs
2021-01-24 20:53:39

我使用md5 grunt 任务来生成 MD5 文件名。现在我想在任务的回调中使用新文件名重命名 HTML 文件中的源。我想知道什么是最简单的方法来做到这一点。

6个回答

您可以使用简单的正则表达式:

var result = fileAsString.replace(/string to be replaced/g, 'replacement');

所以...

var fs = require('fs')
fs.readFile(someFile, 'utf8', function (err,data) {
  if (err) {
    return console.log(err);
  }
  var result = data.replace(/string to be replaced/g, 'replacement');

  fs.writeFile(someFile, result, 'utf8', function (err) {
     if (err) return console.log(err);
  });
});
抱歉,我知道 utf-8 支持多种语言,例如:越南语、中文...
2021-03-17 20:53:39
也许有一个节点module可以实现这一点,但我不知道。顺便说一句,添加了一个完整的示例。
2021-03-19 20:53:39
@Zax:谢谢,我很惊讶这个“错误”能存活这么久;)
2021-03-23 20:53:39
如果您的字符串在文本中多次出现,它将仅替换它找到的第一个字符串。
2021-04-05 20:53:39
当然,但是我是否必须读取文件替换文本然后再次写入文件,或者有更简单的方法,对不起,我更像是一个前端人员。
2021-04-12 20:53:39

由于 replace 对我不起作用,我创建了一个简单的 npm 包replace-in-file来快速替换一个或多个文件中的文本。它部分基于@asgoth 的回答。

编辑(2016 年 10 月 3 日):该包现在支持 promises 和 globs,并且使用说明已更新以反映这一点。

编辑(2018 年 3 月 16 日):该软件包现在每月下载量已超过 10 万次,并且已扩展了附加功能以及 CLI 工具。

安装:

npm install replace-in-file

需要module

const replace = require('replace-in-file');

指定替换选项

const options = {

  //Single file
  files: 'path/to/file',

  //Multiple files
  files: [
    'path/to/file',
    'path/to/other/file',
  ],

  //Glob(s) 
  files: [
    'path/to/files/*.html',
    'another/**/*.path',
  ],

  //Replacement to make (string or regex) 
  from: /Find me/g,
  to: 'Replacement',
};

异步替换Promise:

replace(options)
  .then(changedFiles => {
    console.log('Modified files:', changedFiles.join(', '));
  })
  .catch(error => {
    console.error('Error occurred:', error);
  });

用回调异步替换:

replace(options, (error, changedFiles) => {
  if (error) {
    return console.error('Error occurred:', error);
  }
  console.log('Modified files:', changedFiles.join(', '));
});

同步替换:

try {
  let changedFiles = replace.sync(options);
  console.log('Modified files:', changedFiles.join(', '));
}
catch (error) {
  console.error('Error occurred:', error);
}
我相信它会,但还有一项工作正在进行中以实现更大文件的流媒体替换。
2021-03-14 20:53:39
它是否能够处理大于 256 Mb 的文件大小,因为我在某处读到节点 js 中的字符串限制为 256 Mb
2021-03-16 20:53:39
很好,在我阅读这个 SO 答案之前,我发现并使用了这个包(用于它的 CLI 工具)。爱它
2021-03-17 20:53:39
出色且易于使用的交钥匙module。将它与 async/await 和一个 glob 一起使用在一个相当大的文件夹中,并且速度非常快
2021-03-24 20:53:39
优秀的!这工作超级快速和容易!
2021-03-27 20:53:39

也许“替换”module(www.npmjs.org/package/replace)也适合您。它不需要您读取然后写入文件。

改编自文档:

// install:

npm install replace 

// require:

var replace = require("replace");

// use:

replace({
    regex: "string to be replaced",
    replacement: "replacement string",
    paths: ['path/to/your/file'],
    recursive: true,
    silent: true,
});
您知道如何按路径中的文件扩展名进行过滤吗?类似路径: ['path/to/your/file/*.js'] --> 它不起作用
2021-03-15 20:53:39
还有一个叫做node-replace的维护版本但是,查看代码库,无论是 this 还是 replace-in-file实际上都没有替换文件中的文本,它们使用readFile()并且writeFile()就像接受的答案一样。
2021-03-23 20:53:39
您可以使用 node-glob 将 glob 模式扩展为一组路径,然后遍历它们。
2021-04-05 20:53:39
这很好,但已被放弃。如果您需要开箱即用的解决方案,请参阅stackoverflow.com/a/31040890/1825390以获取维护包。
2021-04-12 20:53:39

您还可以使用 ShellJS 中的“sed”函数...

 $ npm install [-g] shelljs


 require('shelljs/global');
 sed('-i', 'search_pattern', 'replace_pattern', file);

完整的文档...

这似乎是最干净的解决方案:)
2021-03-16 20:53:39
导入第三方依赖并不是最干净的解决方案。
2021-03-18 20:53:39
shx让你从 npm 脚本运行,ShellJs.org 推荐它。github.com/shelljs/shx
2021-03-24 20:53:39
我也喜欢这个。比 npm-module 更好的 oneliner,但代码行 ^^
2021-03-24 20:53:39
这不会做多行。
2021-04-13 20:53:39

您可以在使用流读取的同时处理文件。这就像使用缓冲区,但具有更方便的 API。

var fs = require('fs');
function searchReplaceFile(regexpFind, replace, cssFileName) {
    var file = fs.createReadStream(cssFileName, 'utf8');
    var newCss = '';

    file.on('data', function (chunk) {
        newCss += chunk.toString().replace(regexpFind, replace);
    });

    file.on('end', function () {
        fs.writeFile(cssFileName, newCss, function(err) {
            if (err) {
                return console.log(err);
            } else {
                console.log('Updated!');
            }
    });
});

searchReplaceFile(/foo/g, 'bar', 'file.txt');
但是...如果块分割了 regexpFind 字符串怎么办?那么意图不是失败了吗?
2021-03-22 20:53:39
可能这个片段也应该通过将修改后的文件直接写入文件系统而不是创建一个大变量来改进,因为文件可能大于可用内存。
2021-03-22 20:53:39
@JaakkoKarhu 我制作了一个 npm 包,它将旧块保存在内存中,以防字符串跨越多个块。它被称为stream-replace-string它不适用于正则表达式,但在查找字符串时它是一个有效的解决方案。
2021-03-27 20:53:39
这是一个很好的观点。我想知道是否通过设置bufferSize比您要替换的字符串更长的字符串并保存最后一个块并与当前块连接,您是否可以避免该问题。
2021-04-03 20:53:39