নোডিজ দিয়ে কোনও স্ট্রিং প্রতিস্থাপন করুন


167

আমি এমডি 5 ফাইলের নাম তৈরি করতে এমডি 5 গ্রান্ট টাস্কটি ব্যবহার করি । এখন আমি এইচটিএমএল ফাইলের উত্সগুলির নতুন নামটি কার্যের কলব্যাকের সাথে নতুন নামকরণ করতে চাই। আমি আশ্চর্য হলাম এটি করার সবচেয়ে সহজ উপায় কী।


1
আমি চাই যে কোনও নামকরণকারী এবং প্রতিস্থাপন-ইন-ফাইল সংমিশ্রণ থাকত, যা উভয়ই ফাইলটির নাম পরিবর্তন করে এবং সেই ফাইলগুলির জন্য কোনও রেফারেন্স অনুসন্ধান / প্রতিস্থাপন করতে পারে।
Brain2000

উত্তর:


303

আপনি সাধারণ রেজেক্স ব্যবহার করতে পারেন:

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

অবশ্যই, তবে আমাকে কী ফাইলটি পড়তে হবে এবং পাঠ্যটি প্রতিস্থাপন করুন এবং তারপরে আবার ফাইলটি লিখতে হবে, বা এর চেয়ে সহজ উপায় আছে, দুঃখিত আমি সামনের দিকের লোক of
Andreas Köberle

এটি অর্জনের জন্য হয়ত কোনও নোড মডিউল রয়েছে তবে আমি এটি সম্পর্কে অবগত নই। একটি সম্পূর্ণ উদাহরণ বিটিডব্লু যোগ করা হয়েছে।
asgoth

4
@ জ্যাক্স: ধন্যবাদ, আমি অবাক হয়েছি যে এই 'বাগ' এতদিন বেঁচে থাকতে পারে;)

1
দুঃখিত হিসাবে আমি জানি utf-8 অনেক ভাষা সমর্থন করে যেমন: ভিয়েতনামিজ, চাইনিজ ...
vuhung3990

আপনার পাঠ্যে যদি আপনার স্ট্রিং একাধিকবার উপস্থিত হয় তবে এটি এটি খুঁজে পাওয়া প্রথম স্ট্রিংটিকেই প্রতিস্থাপন করবে।
এল্টনগনক

79

যেহেতু প্রতিস্থাপনটি আমার পক্ষে কাজ করে না, তাই আমি একটি সহজ এনপিএম প্যাকেজটি ইন-ফাইল-প্রতিস্থাপন করেছি এক বা একাধিক ফাইলে টেক্সটটি দ্রুত প্রতিস্থাপনের জন্য । এটি আংশিক @ অ্যাসগোথের উত্তরের ভিত্তিতে।

সম্পাদনা (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);
}

3
টার্ন-কী মডিউলটি দুর্দান্ত এবং সহজেই ব্যবহারযোগ্য। এটি বেশিরভাগ বড় ফোল্ডারের উপরে অ্যাসিঙ্ক / অপেক্ষা এবং একটি গ্লোব সহ ব্যবহৃত হয়েছিল এবং এটি দ্রুত বজ্রপাত করেছিল
ম্যাট ফ্লেচার

এটি ফাইল আকারে আরও 256 এমবি এর সাথে কাজ করতে সক্ষম হবে যেহেতু আমি কোথাও পড়েছি নোড
জেএস-এ

আমি বিশ্বাস করি এটি হবে তবে বড় ফাইলগুলির স্ট্রিমিং প্রতিস্থাপন বাস্তবায়নের কাজও চলছে।
অ্যাডাম রেইস

1
সুন্দর, আমি এই এসও উত্তরটি পড়ার আগে আমি এই প্যাকেজটি খুঁজে পেয়েছি এবং ব্যবহার করেছি (এর সিএলআই সরঞ্জামের জন্য)। এটি পছন্দ
রাসেল চিশলম

38

সম্ভবত "প্রতিস্থাপন" মডিউল ( 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,
});

আপনি কি জানেন যে কীভাবে ফাইলগুলিতে ফাইল এক্সটেনশন দ্বারা ফিল্টার করা যায়? পথের মতো কিছু: ['পাথ / টু / আপনার / ফাইল / *। জেএস'] -> এটি কাজ করে না
কালামারিকো

গ্লোব নিদর্শনগুলিকে পাথের অ্যারেতে প্রসারিত করতে আপনি নোড-গ্লোব ব্যবহার করতে পারেন এবং তারপরে পুনরাবৃত্তি করতে পারেন।
রবডাব্লু

3
এটি দুর্দান্ত, তবে পরিত্যক্ত হয়েছে। আপনি যদি কোনও বক্স-অফ-বাক্সের সমাধান চান তবে রক্ষণাবেক্ষণ প্যাকেজের জন্য stackoverflow.com/a/31040890/1825390 দেখুন ।
xavdid

1
নোড-রিপ্লেস নামে একটি রক্ষণাবেক্ষণ সংস্করণও রয়েছে ; তবে কোড বেস দিকে তাকিয়ে তন্ন তন্ন এই কিংবা প্রতিস্থাপন-ইন-ফাইল আসলে ফাইলে টেক্সট প্রতিস্থাপন, তারা ব্যবহার readFile()এবং writeFile()মাত্র গৃহীত উত্তর চাই।
c1moore

26

আপনি শেলজেএস-এর অংশ যা 'সেড' ফাংশন ব্যবহার করতে পারেন ...

 $ npm install [-g] shelljs


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

আরও উদাহরণের জন্য ShellJs.org দেখুন .org


এটি সবচেয়ে পরিষ্কার সমাধান বলে মনে হচ্ছে :)
ইয়র্কেন

1
shxআপনাকে এনএমপি স্ক্রিপ্টগুলি থেকে চালাতে দেয়, শেলজেএসআর.আর্গ.আর্গ. এটি প্রস্তাবিত। github.com/shelljs/shx
জোশুয়া রবিনসন

আমিও এটি পছন্দ করি এনপিএল-মডিউল থেকে একটি অনেলাইনারের চেয়ে ভাল তবে কোডের জরিপ লাইন ^^

তৃতীয় পক্ষের নির্ভরতা আমদানি করা সবচেয়ে পরিষ্কার সমাধান নয়।
চারটি

এটি মাল্টিলিনগুলি করবে না।
chovy

5

আপনি স্ট্রিম ব্যবহার করে পড়ার সময় ফাইলটি প্রক্রিয়া করতে পারেন। এটি ঠিক বাফার ব্যবহারের মতো তবে আরও সুবিধাজনক এপিআই সহ।

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

3
কিন্তু ... যদি অংশটি রেজিপেক্সফাইন্ড স্ট্রিংটি বিভক্ত হয়? অভিপ্রায় কি তখন ব্যর্থ হয় না?
যাক্কো কারহু

এটি একটি খুব ভাল পয়েন্ট। আমি অবাক হয়েছি যদি bufferSizeআপনি যে স্ট্রিংটির পরিবর্তে এবং শেষ অংশটি সংরক্ষণ করে এবং বর্তমান সমস্যাটির সাথে সামঞ্জস্য করে থাকেন তবে আপনি যদি সমস্যাটি এড়াতে পারেন তবে তার চেয়ে বেশি সময় নির্ধারণ করে ।
সানবার

1
সম্ভবত এই স্নিপেটটি পরিবর্তিত ফাইলটি সরাসরি ফাইল সিস্টেমে লেখার মাধ্যমে একটি বৃহত্তর ভেরিয়েবল তৈরির পরিবর্তে উন্নত করা উচিত কারণ ফাইলটি উপলব্ধ মেমরির চেয়ে বড় হতে পারে।
সানবার

1

একটি ছোট স্টোরহোল্ডারকে একটি বড় স্ট্রিং কোড দিয়ে প্রতিস্থাপন করার সময় আমি সমস্যার মধ্যে পড়েছিলাম।

আমি করছিলাম:

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

আমি এখানে জাভাস্ক্রিপ্টের বিশেষ প্রতিস্থাপনের নিদর্শনগুলি বর্ণনা করেছি । যেহেতু আমি কোডটি প্রতিস্থাপনের স্ট্রিং হিসাবে ব্যবহার করছিলাম তাতে কিছু ছিল$ ছিল তাই এটি আউটপুটটি গোলমাল করছে।

আমার সমাধানটি ছিল ফাংশন রিপ্লেসমেন্ট বিকল্পটি ব্যবহার করা, যা কোনও বিশেষ প্রতিস্থাপন করে না:

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

1

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
}

দ্রষ্টব্য, কেবল ছোট ফাইলগুলির জন্য এগুলি মেমরিতে পড়বে।


bluebirdনেটিভ Promiseএবং ইউজার.প্রোমাইসিফাই ব্যবহার করার দরকার নেই ।
ফ্রান্সিসকো

1
@ ফ্রেঞ্চিসকোমেটো সত্য, তবে 1 বা 2 ফাংশনের বাইরে প্রোমিসিফএল এখনও দুর্দান্ত ব্যবহারযোগ্য।
ম্যাট

1

লিনাক্স বা ম্যাকে, কীপটি সহজ এবং খোলের সাহায্যে কেবল সেড ব্যবহার করুন। কোন বাহ্যিক গ্রন্থাগার প্রয়োজন। নিম্নলিখিত কোড লিনাক্সে কাজ করে।

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`)

ফাইনালের পরে "জি"! " সেড একটি লাইনে সমস্ত দৃষ্টান্ত প্রতিস্থাপন করে। এটি সরান, এবং প্রতি লাইনে প্রথম ঘটনাটি প্রতিস্থাপন করা হবে।


1

@ সানবারের উত্তরে সম্প্রসারণ করা, এটি করার সর্বাধিক দক্ষ উপায় হ'ল আসল ফাইলটি একটি স্ট্রিম হিসাবে পড়া এবং তারপরে প্রতিটি অংশকে একটি নতুন ফাইলে স্ট্রিম করা এবং শেষ পর্যন্ত নতুন ফাইলটি দিয়ে মূল ফাইলটি প্রতিস্থাপন করা।

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

0

আমি এর পরিবর্তে একটি দ্বৈত স্রোত ব্যবহার করব। এখানে ডকুমেন্ট নোডেজ ডক দ্বৈত স্রোত

ট্রান্সফর্ম স্ট্রিম একটি দ্বৈত প্রবাহ যেখানে আউটপুটটি কোনওভাবে ইনপুট থেকে গণনা করা হয়।


0

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

নিশ্চিতরূপে আপনি স্ট্রিম হিসাবে পড়ার জন্য রিডিং টেম্পলেট ফাংশনটিকে উন্নত করতে পারেন এবং এটিকে আরও দক্ষ করে তুলতে লাইন দ্বারা বাইট রচনা করুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.