Sostituisci una stringa in un file con nodejs

Io uso l’ attività grunt md5 per generare nomi di file MD5. Ora voglio rinominare le fonti nel file html con il nuovo nome file nel callback dell’attività. Mi chiedo quale sia il modo più semplice per farlo.

Potresti usare la semplice espressione regolare:

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

Così…

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

Poiché la sostituzione non funzionava per me, ho creato un semplice pacchetto npm sostitutivo per sostituire rapidamente il testo in uno o più file. È parzialmente basato sulla risposta di @ asgoth.

Modifica (3 ottobre 2016) : il pacchetto ora supporta promesse e glob e le istruzioni per l’uso sono state aggiornate per riflettere questo.

Modifica (16 marzo 2018) : il pacchetto ha accumulato oltre 100.000 download mensili ora ed è stato esteso con funzionalità aggiuntive e uno strumento CLI.

Installare:

 npm install replace-in-file 

Richiedi modulo

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

Specificare le opzioni di sostituzione

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

Sostituzione asincrona con promesse:

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

Sostituzione asincrona con callback:

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

Sostituzione sincrona:

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

Forse il modulo “replace” ( http://www.npmjs.org/package/replace ) funzionerebbe anche per te. Non richiederebbe di leggere e quindi scrivere il file.

Adattato dalla documentazione:

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

Puoi anche usare la funzione ‘sed’ che fa parte di ShellJS …

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

Visita ShellJs.org per ulteriori esempi.

È ansible elaborare il file mentre viene letto utilizzando gli stream. È come usare i buffer ma con un’API più 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'); 

Ho riscontrato problemi durante la sostituzione di un piccolo segnaposto con una grande stringa di codice.

Stavo facendo:

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

Ho capito che il problema erano i modelli di sostituzione speciali di JavaScript, descritti qui . Dal momento che il codice che stavo usando come stringa sostitutiva aveva qualche $ in esso, stava rovinando l’output.

La mia soluzione era usare l’opzione di sostituzione della funzione, che NON fa alcuna sostituzione speciale:

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

Vorrei invece utilizzare un stream duplex. come documentato qui nodejs doc stream duplex

Un stream di trasformazione è uno stream Duplex in cui l’output è calcolato in qualche modo dall’input.

ES2017 / 8 per il nodo 7.6+ con un file di scrittura temporaneo per la sostituzione atomica.

 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 per file di dimensioni ridotte man mano che verranno letti in memoria.