Reemplazar una cadena en un archivo con nodejs

Utilizo la tarea grunt md5 para generar nombres de archivo MD5. Ahora quiero cambiar el nombre de las fonts en el archivo html con el nuevo nombre de archivo en la callback de la tarea. Me pregunto cuál es la forma más fácil de hacer esto.

Puede usar expresiones regulares simples:

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

Asi que…

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

Como el reemplazo no funcionaba para mí, he creado un paquete simple de npm para reemplazar el archivo para reemplazar rápidamente el texto en uno o más archivos. Se basa parcialmente en la respuesta de @ asgoth.

Editar (3 de octubre de 2016) : el paquete ahora admite promesas y comodines, y las instrucciones de uso se han actualizado para reflejar esto.

Editar (16 de marzo de 2018) : el paquete ha acumulado más de 100 mil descargas mensuales ahora y se ha ampliado con funciones adicionales, así como una herramienta de CLI.

Instalar:

 npm install replace-in-file 

Requiere módulo

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

Especificar opciones de reemplazo

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

Reemplazo asincrónico con promesas:

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

Reemplazo asincrónico con callback:

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

Reemplazo síncrono:

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

Quizás el módulo “reemplazar” ( http://www.npmjs.org/package/replace ) también funcione para usted. No es necesario que lea y luego escriba el archivo.

Adaptado de la documentación:

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

También puede usar la función ‘sed’ que es parte de ShellJS …

  $ npm install [-g] shelljs require('shelljs/global'); sed('-i', 'search_pattern', 'replace_pattern', file); 

Visite ShellJs.org para obtener más ejemplos.

Puede procesar el archivo mientras se lee utilizando secuencias. Es como usar memorias intermedias pero con una API más conveniente.

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

Me encontré con problemas al reemplazar un pequeño marcador de posición con una gran cadena de código.

Estaba haciendo:

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

Descubrí que el problema eran los patrones de reemplazo especiales de JavaScript, que se describen aquí . Como el código que estaba usando como cadena de reemplazo tenía algunos $ en él, estaba estropeando la salida.

Mi solución fue utilizar la opción de reemplazo de función, que NO hace ningún reemplazo especial:

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

Yo usaría una transmisión dúplex en su lugar. como documentado aquí nodejs doc duplex streams

Una transmisión de transformación es una secuencia dúplex donde la salida se calcula de alguna manera desde la entrada.

ES2017 / 8 para el nodo 7.6+ con un archivo de escritura temporal para reemplazo atómico.

 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 } 

Nota: solo para archivos pequeños, ya que se leerán en la memoria.