मैं MD5 फ़ाइल नाम उत्पन्न करने के लिए md5 ग्रंट कार्य का उपयोग करता हूं । अब मैं कार्य के कॉलबैक में नए फ़ाइलनाम के साथ HTML फ़ाइल में स्रोतों का नाम बदलना चाहता हूं। मुझे आश्चर्य है कि ऐसा करने का सबसे आसान तरीका क्या है।
मैं MD5 फ़ाइल नाम उत्पन्न करने के लिए md5 ग्रंट कार्य का उपयोग करता हूं । अब मैं कार्य के कॉलबैक में नए फ़ाइलनाम के साथ HTML फ़ाइल में स्रोतों का नाम बदलना चाहता हूं। मुझे आश्चर्य है कि ऐसा करने का सबसे आसान तरीका क्या है।
जवाबों:
आप सरल regex का उपयोग कर सकते हैं:
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);
});
});
चूंकि प्रतिस्थापन मेरे लिए काम नहीं कर रहा था, इसलिए मैंने एक सरल या एक से अधिक फाइलों में टेक्स्ट को बदलने के लिए एक साधारण एनपीएम पैकेज रिप्ले -इन-फाइल बनाया है। यह आंशिक रूप से @ asgoth के उत्तर पर आधारित है।
संपादित करें (3 अक्टूबर 2016) : पैकेज अब वादे और ग्लब्स का समर्थन करता है, और इसे दर्शाने के लिए उपयोग के निर्देशों को अपडेट किया गया है।
संपादित करें (16 मार्च 2018) : पैकेज को अब 100k मासिक डाउनलोड से अधिक प्राप्त किया गया है और अतिरिक्त सुविधाओं के साथ-साथ सीएलआई उपकरण के साथ बढ़ाया गया है।
इंस्टॉल:
npm install replace-in-file
मॉड्यूल की आवश्यकता है
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',
};
वादों के साथ अतुल्यकालिक प्रतिस्थापन:
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);
}
शायद "बदलें" मॉड्यूल ( 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,
});
readFile()
और writeFile()
स्वीकृत उत्तर की तरह।
आप 'sed' फंक्शन का भी उपयोग कर सकते हैं जो ShellJS का हिस्सा है ...
$ npm install [-g] shelljs
require('shelljs/global');
sed('-i', 'search_pattern', 'replace_pattern', file);
अधिक उदाहरणों के लिए ShellJs.org पर जाएं ।
shx
आपको npm स्क्रिप्ट से चलाने की अनुमति देता है, ShellJs.org ने इसकी सिफारिश की। github.com/shelljs/shx
आप धाराओं का उपयोग करके पढ़े जाने के दौरान फ़ाइल को संसाधित कर सकते हैं। यह सिर्फ बफ़र्स का उपयोग करने जैसा है लेकिन अधिक सुविधाजनक एपीआई के साथ।
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');
bufferSize
आप उस स्ट्रिंग की तुलना में लंबे समय तक सेट कर रहे हैं जिसे आप बदल रहे हैं और अंतिम चंक को सहेज रहे हैं और उस समस्या से बच सकते हैं जिसे आप वर्तमान समस्या से बचा सकते हैं।
कोड के एक बड़े स्ट्रिंग के साथ एक छोटे प्लेसहोल्डर को प्रतिस्थापित करते समय मैं मुद्दों में भाग गया।
मैं कर रहा था:
var replaced = original.replace('PLACEHOLDER', largeStringVar);
मुझे लगा कि समस्या जावास्क्रिप्ट का विशेष प्रतिस्थापन पैटर्न है, यहां वर्णित है । चूँकि मैं कोड का उपयोग कर रहा था, क्योंकि इसमें स्ट्रिंग की जगह कुछ थी $
, यह आउटपुट को गड़बड़ कर रहा था।
मेरा समाधान फ़ंक्शन प्रतिस्थापन विकल्प का उपयोग करना था, जो कोई विशेष प्रतिस्थापन नहीं करता है:
var replaced = original.replace('PLACEHOLDER', function() {
return largeStringVar;
});
परमाणु प्रतिस्थापन के लिए अस्थायी लेखन फ़ाइल के साथ नोड 7.6 7.6 के लिए ES2017 / 8।
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
}
ध्यान दें, केवल स्मॉलिश फाइल्स के लिए क्योंकि उन्हें मेमोरी में पढ़ा जाएगा।
लिनक्स या मैक पर, सिम्पल सरल है और सिर्फ शेल के साथ सेड का उपयोग करें। किसी बाहरी पुस्तकालय की आवश्यकता नहीं है। निम्न कोड लिनक्स पर काम करता है।
const shell = require('child_process').execSync
shell(`sed -i "s!oldString!newString!g" ./yourFile.js`)
मैक पर सिंटैक्स थोड़ा अलग है। मैं अभी इसका परीक्षण नहीं कर सकता, लेकिन मेरा मानना है कि आपको "-i" के बाद खाली स्ट्रिंग जोड़ने की आवश्यकता है।
const shell = require('child_process').execSync
shell(`sed -i "" "s!oldString!newString!g" ./yourFile.js`)
"जी" फाइनल के बाद "!" बनाता है sed एक लाइन पर सभी उदाहरणों को प्रतिस्थापित करता है। इसे निकालें, और प्रति पंक्ति केवल पहली घटना को प्रतिस्थापित किया जाएगा।
@ Sanbor के उत्तर पर विस्तार करते हुए, ऐसा करने का सबसे प्रभावी तरीका मूल फ़ाइल को एक स्ट्रीम के रूप में पढ़ना है, और फिर प्रत्येक चंक को एक नई फ़ाइल में स्ट्रीम करना है, और फिर मूल फ़ाइल को नई फ़ाइल के साथ बदलना है।
async function findAndReplaceFile(regexFindPattern, replaceValue, originalFile) {
const updatedFile = `${originalFile}.updated`;
return new Promise((resolve, reject) => {
const readStream = fs.createReadStream(originalFile, { encoding: 'utf8', autoClose: true });
const writeStream = fs.createWriteStream(updatedFile, { encoding: 'utf8', autoClose: true });
// For each chunk, do the find & replace, and write it to the new file stream
readStream.on('data', (chunk) => {
chunk = chunk.toString().replace(regexFindPattern, replaceValue);
writeStream.write(chunk);
});
// Once we've finished reading the original file...
readStream.on('end', () => {
writeStream.end(); // emits 'finish' event, executes below statement
});
// Replace the original file with the updated file
writeStream.on('finish', async () => {
try {
await _renameFile(originalFile, updatedFile);
resolve();
} catch (error) {
reject(`Error: Error renaming ${originalFile} to ${updatedFile} => ${error.message}`);
}
});
readStream.on('error', (error) => reject(`Error: Error reading ${originalFile} => ${error.message}`));
writeStream.on('error', (error) => reject(`Error: Error writing to ${updatedFile} => ${error.message}`));
});
}
async function _renameFile(oldPath, newPath) {
return new Promise((resolve, reject) => {
fs.rename(oldPath, newPath, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
// Testing it...
(async () => {
try {
await findAndReplaceFile(/"some regex"/g, "someReplaceValue", "someFilePath");
} catch(error) {
console.log(error);
}
})()
मैं इसके बजाय एक द्वैध प्रवाह का उपयोग करेगा। यहाँ दस्तावेज की तरह नोडज डॉक डुप्लेक्स धाराएँ
एक ट्रांसफ़ॉर्म स्ट्रीम एक डुप्लेक्स स्ट्रीम है जहाँ इनपुट से आउटपुट की गणना किसी तरह से की जाती है।
<p>Please click in the following {{link}} to verify the account</p>
function renderHTML(templatePath: string, object) {
const template = fileSystem.readFileSync(path.join(Application.staticDirectory, templatePath + '.html'), 'utf8');
return template.match(/\{{(.*?)\}}/ig).reduce((acc, binding) => {
const property = binding.substring(2, binding.length - 2);
return `${acc}${template.replace(/\{{(.*?)\}}/, object[property])}`;
}, '');
}
renderHTML(templateName, { link: 'SomeLink' })
यह सुनिश्चित करने के लिए कि आप स्ट्रीम के रूप में पढ़ने के लिए रीडिंग टेम्प्लेट फ़ंक्शन को बेहतर बना सकते हैं और इसे और अधिक कुशल बनाने के लिए लाइन द्वारा बाइट्स की रचना कर सकते हैं