用nodejs替换文件中的字符串

时间:2021-12-24 01:58:50

I use the md5 grunt task to generate MD5 filenames. Now I wanna rename the sources in the html file with the new filename in the callback of the task. I wonder whats the easiest way to do this.

我使用md5 grunt任务生成md5文件名。现在我想将html文件中的源重命名为任务回调中的新文件名。我想知道最简单的方法是什么。

8 个解决方案

#1


172  

You could use simple regex:

您可以使用简单的regex:

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

So...

所以…

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);
  });
});

#2


29  

Since replace wasn't working for me, I've created a simple npm package replace-in-file to quickly replace text in one or more files. It's partially based on @asgoth's answer.

由于replace对我不起作用,所以我创建了一个简单的npm包replac中期文件来快速替换一个或多个文件中的文本。部分是基于@asgoth的答案。

Edit (3 October 2016): The package now supports promises and globs, and the usage instructions have been updated to reflect this.

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

Edit (16 March 2018): The package has amassed over 100k monthly downloads now and has been extended with additional features as well as a CLI tool.

编辑(2018年3月16日):该软件包现在已经积累了超过100k的月下载,并且已经扩展了额外的功能和CLI工具。

Install:

安装:

npm install replace-in-file

Require module

需要的模块

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

Specify replacement options

指定替代选项

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',
};

Asynchronous replacement with promises:

异步替代承诺:

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

Asynchronous replacement with callback:

替代异步回调:

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

Synchronous replacement:

同步替换:

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

#3


26  

Perhaps the "replace" module (www.npmjs.org/package/replace) also would work for you. It would not require you to read and then write the file.

或许“替换”模块(www.npmjs.org/package/replace)也适合你。它不需要你读然后写文件。

Adapted from the documentation:

改编自文档:

// 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,
});

#4


23  

You can also use the 'sed' function that's part of ShellJS ...

你也可以使用“sed”功能,这是shell的一部分…

 $ npm install [-g] shelljs


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

Visit ShellJs.org for more examples.

请访问ShellJs.org以获得更多的示例。

#5


5  

You could process the file while being read by using streams. It's just like using buffers but with a more convenient API.

您可以通过使用流来处理文件。这就像使用缓冲区,但是使用更方便的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');

#6


1  

I ran into issues when replacing a small placeholder with a large string of code.

我在用大串代码替换小占位符时遇到了问题。

I was doing:

我在做:

var replaced = original.replace('PLACEHOLDER', largeStringVar);

I figured out the problem was JavaScript's special replacement patterns, described here. Since the code I was using as the replacing string had some $ in it, it was messing up the output.

我发现问题出在JavaScript的特殊替换模式上。由于我作为替换字符串使用的代码中有一些$,所以会导致输出混乱。

My solution was to use the function replacement option, which DOES NOT do any special replacement:

我的解决方案是使用功能替换选项,它不做任何特殊的替换:

var replaced = original.replace('PLACEHOLDER', function() {
    return largeStringVar;
});

#7


0  

I would use a duplex stream instead. like documented here nodejs doc duplex streams

我将使用双工流。就像这里记录的nodejs doc双工流

A Transform stream is a Duplex stream where the output is computed in some way from the input.

转换流是一种双工流,其中输出以某种方式从输入中计算。

#8


0  

ES2017/8 for Node 7.6+ with a temporary write file for atomic replacement.

ES2017/8用于节点7.6+,带有用于原子替换的临时写文件。

const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))

async function replaceRegexInFile(file, search, replace){
  let contents = await fs.readFileAsync(file, 'utf8')
  let replaced_contents = contents.replace(search, replace)
  let tmpfile = `${file}.jstmpreplace`
  await fs.writeFileAsync(tmpfile, replaced_contents, 'utf8')
  await fs.renameAsync(tmpfile, file)
  return true
}

Note, only for smallish files as they will be read into memory.

注意,只用于小文件,因为它们将被读入内存。

#1


172  

You could use simple regex:

您可以使用简单的regex:

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

So...

所以…

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);
  });
});

#2


29  

Since replace wasn't working for me, I've created a simple npm package replace-in-file to quickly replace text in one or more files. It's partially based on @asgoth's answer.

由于replace对我不起作用,所以我创建了一个简单的npm包replac中期文件来快速替换一个或多个文件中的文本。部分是基于@asgoth的答案。

Edit (3 October 2016): The package now supports promises and globs, and the usage instructions have been updated to reflect this.

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

Edit (16 March 2018): The package has amassed over 100k monthly downloads now and has been extended with additional features as well as a CLI tool.

编辑(2018年3月16日):该软件包现在已经积累了超过100k的月下载,并且已经扩展了额外的功能和CLI工具。

Install:

安装:

npm install replace-in-file

Require module

需要的模块

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

Specify replacement options

指定替代选项

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',
};

Asynchronous replacement with promises:

异步替代承诺:

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

Asynchronous replacement with callback:

替代异步回调:

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

Synchronous replacement:

同步替换:

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

#3


26  

Perhaps the "replace" module (www.npmjs.org/package/replace) also would work for you. It would not require you to read and then write the file.

或许“替换”模块(www.npmjs.org/package/replace)也适合你。它不需要你读然后写文件。

Adapted from the documentation:

改编自文档:

// 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,
});

#4


23  

You can also use the 'sed' function that's part of ShellJS ...

你也可以使用“sed”功能,这是shell的一部分…

 $ npm install [-g] shelljs


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

Visit ShellJs.org for more examples.

请访问ShellJs.org以获得更多的示例。

#5


5  

You could process the file while being read by using streams. It's just like using buffers but with a more convenient API.

您可以通过使用流来处理文件。这就像使用缓冲区,但是使用更方便的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');

#6


1  

I ran into issues when replacing a small placeholder with a large string of code.

我在用大串代码替换小占位符时遇到了问题。

I was doing:

我在做:

var replaced = original.replace('PLACEHOLDER', largeStringVar);

I figured out the problem was JavaScript's special replacement patterns, described here. Since the code I was using as the replacing string had some $ in it, it was messing up the output.

我发现问题出在JavaScript的特殊替换模式上。由于我作为替换字符串使用的代码中有一些$,所以会导致输出混乱。

My solution was to use the function replacement option, which DOES NOT do any special replacement:

我的解决方案是使用功能替换选项,它不做任何特殊的替换:

var replaced = original.replace('PLACEHOLDER', function() {
    return largeStringVar;
});

#7


0  

I would use a duplex stream instead. like documented here nodejs doc duplex streams

我将使用双工流。就像这里记录的nodejs doc双工流

A Transform stream is a Duplex stream where the output is computed in some way from the input.

转换流是一种双工流,其中输出以某种方式从输入中计算。

#8


0  

ES2017/8 for Node 7.6+ with a temporary write file for atomic replacement.

ES2017/8用于节点7.6+,带有用于原子替换的临时写文件。

const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))

async function replaceRegexInFile(file, search, replace){
  let contents = await fs.readFileAsync(file, 'utf8')
  let replaced_contents = contents.replace(search, replace)
  let tmpfile = `${file}.jstmpreplace`
  await fs.writeFileAsync(tmpfile, replaced_contents, 'utf8')
  await fs.renameAsync(tmpfile, file)
  return true
}

Note, only for smallish files as they will be read into memory.

注意,只用于小文件,因为它们将被读入内存。