কোনও প্যাটার্নের জন্য ফাইল পাঠ্য কীভাবে সন্ধান করবেন এবং প্রদত্ত মানের সাথে এটি প্রতিস্থাপন করুন


117

আমি কোনও প্যাটার্নের জন্য কোনও ফাইল (বা ফাইলগুলির তালিকা) অনুসন্ধান করার জন্য একটি স্ক্রিপ্ট খুঁজছি এবং যদি পাওয়া যায় তবে সেই মানটিকে একটি নির্দিষ্ট মান দিয়ে প্রতিস্থাপন করব।

থটস?


1
নীচের উত্তরগুলিতে, সচেতন থাকুন যে বড় ফাইলগুলি স্লাপিং কেন খারাপ, File.readতা ব্যবহারের জন্য যে কোনও প্রস্তাবনাগুলি স্ট্যাকওভারফ্লো . com/a/25189286/128421 এ তথ্য দিয়ে মেজাজ করা দরকার । পরিবর্তে File.open(filename, "w") { |file| file << content }পরিবর্তনের পরিবর্তে ব্যবহার করুন File.write(filename, content)
টিন ম্যান

উত্তর:


190

অস্বীকৃতি: এই পদ্ধতিটি রুবির ক্ষমতার একটি নিখুঁত চিত্র, এবং ফাইলগুলিতে স্ট্রিং প্রতিস্থাপনের জন্য উত্পাদন-গ্রেড সমাধান নয়। এটি বিভিন্ন ব্যর্থতার পরিস্থিতিতে যেমন ক্রাশ, বিঘ্নিত বা ডিস্ক পূর্ণ হওয়ার ক্ষেত্রে ডেটা হারাতে পারে। এই কোডটি দ্রুত ওয়ান-অফ স্ক্রিপ্টের বাইরে এমন কোনও কিছুর জন্য উপযুক্ত নয় যেখানে সমস্ত ডেটা ব্যাক আপ হয়। যে কারণে, আপনার প্রোগ্রামগুলিতে এই কোডটি অনুলিপি করবেন না।

এটি করার জন্য এখানে একটি দ্রুত সংক্ষিপ্ত উপায়।

file_names = ['foo.txt', 'bar.txt']

file_names.each do |file_name|
  text = File.read(file_name)
  new_contents = text.gsub(/search_regexp/, "replacement string")

  # To merely print the contents of the file, use:
  puts new_contents

  # To write changes to the file, use:
  File.open(file_name, "w") {|file| file.puts new_contents }
end

ফাইলগুলি কী পরিবর্তনগুলি আবার লিখতে দেয়? আমি ভেবেছিলাম যে এটি কনসোলে কেবল সামগ্রীটি মুদ্রণ করবে।
ডেন ও'কনোর

হ্যাঁ, এটি কনসোলে সামগ্রীটি মুদ্রণ করে।
sepp2k

7
হ্যাঁ, আমি নিশ্চিত নই যে আপনি যা চেয়েছিলেন তা। ফাইল.ওপেন লিখতে (ফাইলের নাম, "ডাব্লু") {| ফাইল | file.puts আউটপুট_এফ_গসব}
সর্বোচ্চ

7
আমাকে ফাইল.ওরাইট: ফাইল.ওপেন (ফাইলের নাম, "ডাব্লু") {| ফাইল | ব্যবহার করতে হয়েছিল file.writ (পাঠ্য)}
আস্তেন

3
লেখার ফাইল করতে, এটি দিয়ে রাখে 'লাইন প্রতিস্থাপনFile.write(file_name, text.gsub(/regexp/, "replace")
আঁট

106

প্রকৃতপক্ষে, রুবিতে একটি জায়গা-তে সম্পাদনা বৈশিষ্ট্য রয়েছে। পার্লের মতো, আপনি বলতে পারেন

ruby -pi.bak -e "gsub(/oldtext/, 'newtext')" *.txt

এটি বর্তমান ডিরেক্টরিতে সমস্ত ফাইলের ডাবল-কোটে কোড প্রয়োগ করবে যার নাম ".txt" দিয়ে শেষ হবে। সম্পাদিত ফাইলগুলির ব্যাকআপ অনুলিপি একটি ".bak" এক্সটেনশন ("foobar.txt.bak" আমার মনে হয়) দিয়ে তৈরি করা হবে।

দ্রষ্টব্য: এটি বহু লাইন অনুসন্ধানের জন্য কাজ করে না বলে মনে হচ্ছে। তাদের জন্য, আপনাকে এটিকে আরও কম সুন্দর উপায়ে করতে হবে, রেজেসের চারপাশে মোড়ক স্ক্রিপ্ট সহ।


1
হেইক পাই পাই? তা ছাড়া, আমি একটি ত্রুটি পেয়েছি। -e: 1: <main>': undefined method gsub ' in the main: অবজেক্ট (NoMethodError)
নিনাদ

15
@ নিনাদপচপুট জায়গাটিতে -iসম্পাদনা করে। .bakব্যাকআপ ফাইলের জন্য ব্যবহৃত এক্সটেনশন (alচ্ছিক)। -pভালো কিছু হয় while gets; <script>; puts $_; end। ( $_সর্বশেষ পঠিত লাইন, তবে আপনি এর মতো echo aa | ruby -p -e '$_.upcase!'
কোনও কিছুর

1
আপনি যদি ফাইলটি পরিবর্তন করতে চান তবে এটি গৃহীত উত্তরের চেয়ে ভাল উত্তর, আইএমএইচও।
কলিন কে

6
আমি এটি কোনও রুবি স্ক্রিপ্টের মধ্যে কীভাবে ব্যবহার করতে পারি ??
সৌরভ

1
এটি ভুল হতে পারে এমন অনেকগুলি উপায় রয়েছে সুতরাং একটি সমালোচনামূলক ফাইলের বিরুদ্ধে চেষ্টা করার আগে এটি ভাল করে পরীক্ষা করুন।
টিন ম্যান

49

মনে রাখবেন যে, আপনি যখন এটি করেন, ফাইল সিস্টেমটি জায়গার বাইরে চলে যেতে পারে এবং আপনি একটি শূন্য দৈর্ঘ্যের ফাইল তৈরি করতে পারেন। সিস্টেম কনফিগারেশন পরিচালনার অংশ হিসাবে আপনি যদি / etc / passwd ফাইলগুলি লেখার মতো কিছু করে থাকেন তবে এটি বিপর্যয়কর।

নোট করুন যে স্থানটিতে থাকা ফাইল সম্পাদনা গ্রহণযোগ্য উত্তরের মতো সর্বদা ফাইলটি কেটে ফেলা হবে এবং ক্রমান্বয়ে নতুন ফাইলটি লিখবে। সর্বদা একটি দৌড়ের শর্ত থাকবে যেখানে সহবর্তী পাঠকরা একটি বিচ্ছিন্ন ফাইল দেখতে পাবেন। প্রক্রিয়াটি যদি লেখার সময় কোনও কারণে (সিটিআরএল-সি, ওওএম কিলার, সিস্টেম ক্র্যাশ, বিদ্যুৎ বিভ্রাট ইত্যাদির জন্য) বাতিল হয়ে যায় তবে সংক্ষিপ্ত ফাইলটিও ছেড়ে দেওয়া হবে, যা বিপর্যয়কর হতে পারে। এটি ডেটালোস দৃশ্যের এক ধরণের যা বিকাশকারীদের বিবেচনা করা উচিত কারণ এটি ঘটবে। যে কারণে, আমি মনে করি গ্রহণযোগ্য উত্তরটি সম্ভবত গ্রহণযোগ্য উত্তর হওয়া উচিত নয়। খুব কম সময়ে একটি টেম্পাইল লিখুন এবং এই উত্তরের শেষে ফাইলটি "সরল" সমাধানের মতো জায়গায় নাম পরিবর্তন / নামকরণ করুন।

আপনার একটি অ্যালগরিদম ব্যবহার করা দরকার যা:

  1. পুরানো ফাইল পড়ে এবং নতুন ফাইলটি লিখে দেয়। (পুরো ফাইলগুলিকে স্মৃতিতে স্লুপিং করা সম্পর্কে আপনাকে সতর্ক হওয়া দরকার)

  2. স্পষ্টতই নতুন অস্থায়ী ফাইলটি বন্ধ করে দেয়, যেখানে আপনি কোনও ব্যতিক্রম ছুঁড়ে ফেলতে পারেন কারণ কোনও স্থান নেই বলে ফাইল বাফারগুলি ডিস্কে লেখা যায় না। (এটি ধরুন এবং যদি আপনি চান তবে অস্থায়ী ফাইলটি সাফ করুন, তবে আপনাকে কিছু পুনর্বিবেচনা করতে হবে বা এই মুহুর্তে মোটামুটি কঠোরভাবে ব্যর্থ হওয়া উচিত।

  3. নতুন ফাইলে ফাইলের অনুমতি এবং মোডগুলি স্থির করে।

  4. নতুন ফাইলটির নাম পরিবর্তন করে এটিকে জায়গায় ফেলে দেয়।

Ext3 ফাইল সিস্টেমে আপনার গ্যারান্টি রয়েছে যে ফাইলটি জায়গায় স্থানান্তরিত করতে মেটাডেটা রাইটিং ফাইল সিস্টেম দ্বারা পুনরায় সাজানো হবে না এবং নতুন ফাইলের জন্য ডেটা বাফার লেখার আগে এটি লিখিত হবে না, সুতরাং এটি সফল বা ব্যর্থ হওয়া উচিত। এক্সট 4 ফাইল সিস্টেমটিও এই জাতীয় আচরণকে সমর্থন করার জন্য প্যাচ করা হয়েছে। আপনি যদি খুব ভৌতিক fdatasync()হয়ে থাকেন তবে ফাইলটি জায়গায় স্থানান্তরিত করার আগে আপনার কম্পিউটার কলটি ৩.৫ পদক্ষেপ হিসাবে কল করা উচিত।

ভাষা নির্বিশেষে, এটি সর্বোত্তম অনুশীলন। যে ভাষাগুলিতে কলিং close()কোনও ব্যতিক্রম (পার্ল বা সি) ছুঁড়ে না ফেলে সেগুলিতে আপনাকে অবশ্যই স্পষ্টভাবে ফেরতটি যাচাই করতে হবে close()এবং ব্যর্থ হলে ব্যতিক্রম ছুঁড়ে ফেলতে হবে।

কেবলমাত্র মেমরিতে ফাইল স্লার্প করতে, এটিকে ম্যানিপুলেট করুন এবং ফাইলটিতে লিখতে উপরের পরামর্শটি একটি পূর্ণ ফাইল সিস্টেমে শূন্য দৈর্ঘ্যের ফাইল তৈরির নিশ্চয়তা পাবে। সম্পূর্ণ লিখিত অস্থায়ী ফাইলটিকে জায়গায় স্থানান্তর করতে আপনার সর্বদা ব্যবহার FileUtils.mvকরা উচিত।

একটি চূড়ান্ত বিবেচনা হ'ল অস্থায়ী ফাইল স্থাপন করা। আপনি / টিএমপি-তে কোনও ফাইল খুললে আপনাকে কয়েকটি সমস্যা বিবেচনা করতে হবে:

  • যদি / টিএমপি অন্য কোনও ফাইল সিস্টেমে মাউন্ট করা থাকে তবে আপনি ফাইলটি লেখার আগে আপনি স্থান / টেম্প্প চালিয়ে যেতে পারেন যা অন্যথায় পুরানো ফাইলের গন্তব্যে মোতায়েনযোগ্য।

  • সম্ভবত আরও গুরুত্বপূর্ণ, আপনি যখন mvকোনও ডিভাইস মাউন্ট জুড়ে ফাইলটি চেষ্টা করবেন আপনি স্বচ্ছভাবে cpআচরণে রূপান্তরিত হবেন । পুরানো ফাইলটি খোলা হবে, পুরাতন ফাইলের ইনোড সংরক্ষণ এবং পুনরায় খোলা হবে এবং ফাইলের বিষয়বস্তু অনুলিপি করা হবে। এটি সম্ভবত আপনি যা চান তা নয়, এবং যদি আপনি চলমান ফাইলের বিষয়বস্তু সম্পাদনা করার চেষ্টা করেন তবে আপনি "টেক্সট ফাইল ব্যস্ত" ত্রুটিতে চলে যেতে পারেন। এটি ফাইল সিস্টেম mvকমান্ডগুলি ব্যবহারের উদ্দেশ্যকেও পরাভূত করে এবং আপনি কেবলমাত্র একটি আংশিক লিখিত ফাইলের সাহায্যে গন্তব্য ফাইল সিস্টেমটি স্থানের বাইরে চালাতে পারেন।

    রুবির বাস্তবায়নের সাথেও এর কোনও যোগসূত্র নেই। সিস্টেম mvএবং cpকমান্ড একই আচরণ করে।

এর চেয়ে বেশি পছন্দনীয় হ'ল পুরানো ফাইলের মতো একই ডিরেক্টরিতে একটি টেম্পফিল খোলা। এটি নিশ্চিত করে যে কোনও ক্রস-ডিভাইস সরানোর সমস্যা থাকবে না। mvনিজেই ব্যর্থ না করা উচিত এবং আপনি সবসময় এমন একটি সম্পূর্ণ এবং untruncated ফাইল পাওয়া উচিত। যেকোন ব্যর্থতা যেমন স্থানের বাইরে ডিভাইস, অনুমতি ত্রুটি ইত্যাদি Temp টেম্পফিল লেখার সময় মুখোমুখি হওয়া উচিত।

গন্তব্য ডিরেক্টরিতে টেম্পফিল তৈরির পদ্ধতির একমাত্র ডাউনসাইডগুলি হ'ল:

  • কখনও কখনও আপনি সেখানে কোনও টেম্পফিল খুলতে পারবেন না, যেমন আপনি উদাহরণস্বরূপ / প্রোকে কোনও ফাইল সম্পাদনা করার চেষ্টা করছেন। যে কারণে আপনি পিছিয়ে পড়তে এবং গন্তব্য ডিরেক্টরিতে ফাইলটি খুলতে ব্যর্থ হলে / টিএমপি চেষ্টা করতে চাইতে পারেন।
  • সম্পূর্ণ পুরানো ফাইল এবং নতুন ফাইল উভয় ধরে রাখতে আপনার অবশ্যই গন্তব্য পার্টিশনে পর্যাপ্ত স্থান থাকতে হবে। তবে, যদি আপনার উভয় অনুলিপি রাখার জন্য পর্যাপ্ত জায়গা না থাকে তবে আপনি সম্ভবত ডিস্কের জায়গাতেই সংক্ষিপ্ত এবং কাটা ফাইল লেখার প্রকৃত ঝুঁকি অনেক বেশি, সুতরাং আমি যুক্তি দেব যে এটি কিছুটা সংকীর্ণের বাইরে খুব দুর্বল ট্রেড অফ and -মনিটরেড) এজ কেস

এখানে কিছু কোড যা সম্পূর্ণ অ্যালগরিদম প্রয়োগ করে (উইন্ডোজ কোডটি অন্বেষিত এবং অসমাপ্ত):

#!/usr/bin/env ruby

require 'tempfile'

def file_edit(filename, regexp, replacement)
  tempdir = File.dirname(filename)
  tempprefix = File.basename(filename)
  tempprefix.prepend('.') unless RUBY_PLATFORM =~ /mswin|mingw|windows/
  tempfile =
    begin
      Tempfile.new(tempprefix, tempdir)
    rescue
      Tempfile.new(tempprefix)
    end
  File.open(filename).each do |line|
    tempfile.puts line.gsub(regexp, replacement)
  end
  tempfile.fdatasync unless RUBY_PLATFORM =~ /mswin|mingw|windows/
  tempfile.close
  unless RUBY_PLATFORM =~ /mswin|mingw|windows/
    stat = File.stat(filename)
    FileUtils.chown stat.uid, stat.gid, tempfile.path
    FileUtils.chmod stat.mode, tempfile.path
  else
    # FIXME: apply perms on windows
  end
  FileUtils.mv tempfile.path, filename
end

file_edit('/tmp/foo', /foo/, "baz")

এবং এখানে একটি সামান্য কঠোর সংস্করণ যা প্রতিটি সম্ভাব্য প্রান্তের মামলা সম্পর্কে চিন্তা করে না (যদি আপনি ইউনিক্সে থাকেন এবং / প্রোকে লেখার বিষয়ে চিন্তা করেন না):

#!/usr/bin/env ruby

require 'tempfile'

def file_edit(filename, regexp, replacement)
  Tempfile.open(".#{File.basename(filename)}", File.dirname(filename)) do |tempfile|
    File.open(filename).each do |line|
      tempfile.puts line.gsub(regexp, replacement)
    end
    tempfile.fdatasync
    tempfile.close
    stat = File.stat(filename)
    FileUtils.chown stat.uid, stat.gid, tempfile.path
    FileUtils.chmod stat.mode, tempfile.path
    FileUtils.mv tempfile.path, filename
  end
end

file_edit('/tmp/foo', /foo/, "baz")

সত্যিই সরল ইউজ-কেস, যখন আপনি ফাইল সিস্টেমের অনুমতিগুলির বিষয়ে চিন্তা করেন না (হয় আপনি রুট হিসাবে চলছেন না, বা আপনি রুট হিসাবে চলছেন এবং ফাইলটি রুটের মালিকানাধীন):

#!/usr/bin/env ruby

require 'tempfile'

def file_edit(filename, regexp, replacement)
  Tempfile.open(".#{File.basename(filename)}", File.dirname(filename)) do |tempfile|
    File.open(filename).each do |line|
      tempfile.puts line.gsub(regexp, replacement)
    end
    tempfile.close
    FileUtils.mv tempfile.path, filename
  end
end

file_edit('/tmp/foo', /foo/, "baz")

টিএল; ডিআর : আপডেটটি পারমাণবিক এবং সমবর্তী পাঠকরা সংক্ষিপ্ত ফাইলগুলি দেখতে পাবে না তা নিশ্চিত করার জন্য সর্বনিম্ন স্বীকৃত উত্তরের পরিবর্তে এটি ব্যবহার করা উচিত। আমি উপরে উল্লিখিত হিসাবে, সম্পাদিত ফাইল হিসাবে একই ডিরেক্টরিতে টেম্পফিল তৈরি করা এখানে জরুরী যাতে ক্রস ডিভাইস এমভি অপারেশনগুলি সিপি অপারেশনগুলিতে অনুবাদ করা যায় যদি / টিএমপি অন্য কোনও ডিভাইসে মাউন্ট করা থাকে। কল করা এফডিট্যাসেন্সিকে প্যারাওইয়ার একটি যুক্ত স্তর, তবে এটি একটি পারফরম্যান্স হিট করতে পারে, তাই এটি সাধারণত অনুশীলন না হওয়ায় আমি এই উদাহরণ থেকে বাদ দিয়েছি।


পরিবর্তে ডিরেক্টরি আপনি আসলে স্বয়ংক্রিয়ভাবে অ্যাপ্লিকেশান ডেটা ডিরেক্টরির মধ্যে এক (Windows এ কোন পথে) তৈরি করবে এটা আছেন একটি টেম্প ফাইল খোলার ও তাদের আপনি একটি file.unlink কি করতে পারেন এটি মুছে ফেলতে ..
13aal

3
এর মধ্যে যে অতিরিক্ত চিন্তাভাবনা ছিল তা আমি সত্যিই প্রশংসা করেছি। একটি শিক্ষানবিস হিসাবে, অভিজ্ঞ দেবগণের চিন্তার নিদর্শনগুলি দেখতে খুব আকর্ষণীয় যে যারা কেবলমাত্র মূল প্রশ্নের উত্তর দিতে পারে না, তবে মূল প্রশ্নের আসলে কী বোঝায় তার বৃহত্তর প্রসঙ্গে মন্তব্যও করে।
রমিজামস

প্রোগ্রামিং কেবল তাত্ক্ষণিক সমস্যা সমাধানের জন্য নয়, অপেক্ষায় থাকা অন্যান্য সমস্যাগুলি এড়াতে সামনের দিকে চিন্তা করাও। অ্যালগরিদমটি কোনও কোণে আঁকানো, কোনও বিশ্রী কুল্জ জোর করে, যখন কোনও ছোট্ট সামঞ্জস্যটি আগে খুব সুন্দর প্রবাহের কারণ হতে পারে, এমন কোডের মুখোমুখি হওয়ার চেয়ে কোনও প্রবীণ বিকাশকারীকে আর কিছুই বিরক্ত করে না। লক্ষ্যটি বোঝার জন্য বিশ্লেষণ করতে ঘন্টা বা কয়েক দিন সময় নিতে পারে এবং তারপরে কয়েকটি লাইন পুরানো কোডের একটি পৃষ্ঠা প্রতিস্থাপন করে। এটি অনেক সময় ডেটা এবং সিস্টেমের বিরুদ্ধে দাবা খেলার মতো।
টিন ম্যান

11

জায়গাগুলি ফাইল সম্পাদনা করার কোনও উপায় নেই isn't আপনি যখন এটির সাথে দূরে সরে যেতে পারেন তখন আপনি যা করেন (যেমন ফাইলগুলি খুব বড় না হয়) তা হ'ল, আপনি ফাইলটি মেমোরিতে পড়েন ( File.read), পড়ার স্ট্রিংয়ে আপনার বিকল্পগুলি সম্পাদন করুন ( String#gsub) এবং তারপরে পরিবর্তিত স্ট্রিংটি আবার লিখুন ফাইল ( File.open, File#write)।

আপনি ব্যবহার করতে পারেন - ফাইল বড় যথেষ্ট যে unfeasible হতে স্বরূপ, আপনি যা করতে হবে তা হন, অংশ ফাইলটি পড়ার (যদি প্যাটার্ন আপনি প্রতিস্থাপন করতে একাধিক লাইনের জুড়ে করা হবে না তারপর এক খণ্ড সাধারণত এক লাইন মানে চাই File.foreachথেকে লাইন দ্বারা একটি ফাইল লাইন পড়ুন), এবং প্রতিটি অংশের জন্য এটি প্রতিস্থাপন সম্পাদন করুন এবং এটি একটি অস্থায়ী ফাইলের সাথে যুক্ত করুন। উত্স ফাইলটি পুনরাবৃত্তি করার পরে, আপনি এটি বন্ধ করে দিন এবং FileUtils.mvঅস্থায়ী ফাইলটির সাথে ওভাররাইট করার জন্য ব্যবহার করেন।


1
আমি স্ট্রিমিং পদ্ধতির পছন্দ করি। আমরা এক সাথে বড় ফাইলগুলির সাথে ডিল করি তাই পুরো ফাইলটি পড়ার জন্য আমাদের কাছে সাধারণত র‌্যামে স্থান থাকে না
শেন

" ফাইলকে" স্লুর্পিং "করা কেন একটি ভাল অনুশীলন নয়? " এর সাথে সম্পর্কিত হতে পারে পড়া পঠন be
টিন ম্যান

9

আরেকটি পদ্ধতি হ'ল রুবির অভ্যন্তরীণ সম্পাদনা ব্যবহার করা (কমান্ড লাইন থেকে নয়):

#!/usr/bin/ruby

def inplace_edit(file, bak, &block)
    old_stdout = $stdout
    argf = ARGF.clone

    argf.argv.replace [file]
    argf.inplace_mode = bak
    argf.each_line do |line|
        yield line
    end
    argf.close

    $stdout = old_stdout
end

inplace_edit 'test.txt', '.bak' do |line|
    line = line.gsub(/search1/,"replace1")
    line = line.gsub(/search2/,"replace2")
    print line unless line.match(/something/)
end

আপনি যদি ব্যাকআপ তৈরি করতে না চান তবে এতে পরিবর্তন '.bak'করুন ''


1
readফাইলটি স্লার্প করার চেষ্টা করার চেয়ে এটি আরও ভাল । এটি স্কেলযোগ্য এবং খুব দ্রুত হওয়া উচিত।
টিন ম্যান

উইন্ডোজে রুবি ২.৩.০ পিপি-র অনুমতি ব্যর্থ হওয়ার জন্য কোথাও একটি বাগ রয়েছে যেখানে একই ফাইলে বেশ কয়েকটি ধারাবাহিক ইনপ্লেস-এডিট ব্লক কাজ করছে। বিভক্ত অনুসন্ধান 1 এবং 2 টি ব্লকে অনুসন্ধান 2 পরীক্ষার পুনরুত্পাদন করতে। পুরোপুরি বন্ধ হচ্ছে না?
21

আমি একসাথে ঘটে যাওয়া কোনও পাঠ্য ফাইলের একাধিক সম্পাদনায় সমস্যা আশা করব। আর কিছু না হলে আপনি খারাপভাবে ম্যাংলেড টেক্সট ফাইল পেতে পারেন।
টিন ম্যান


6

প্রদত্ত ডিরেক্টরিতে সমস্ত ফাইল সন্ধান / প্রতিস্থাপনের জন্য এখানে একটি সমাধান রয়েছে। মূলত আমি সেপ 2 কে প্রদত্ত উত্তর নিয়েছি এবং এটি প্রসারিত করেছি।

# First set the files to search/replace in
files = Dir.glob("/PATH/*")

# Then set the variables for find/replace
@original_string_or_regex = /REGEX/
@replacement_string = "STRING"

files.each do |file_name|
  text = File.read(file_name)
  replace = text.gsub!(@original_string_or_regex, @replacement_string)
  File.open(file_name, "w") { |file| file.puts replace }
end

4
require 'trollop'

opts = Trollop::options do
  opt :output, "Output file", :type => String
  opt :input, "Input file", :type => String
  opt :ss, "String to search", :type => String
  opt :rs, "String to replace", :type => String
end

text = File.read(opts.input)
text.gsub!(opts.ss, opts.rs)
File.open(opts.output, 'w') { |f| f.write(text) }

2
এটি কেন পছন্দের সমাধান এবং এটি কীভাবে কাজ করে তা ব্যাখ্যা করে যদি আপনি কোনও সরবরাহ সরবরাহ করেন তবে এটি আরও সহায়তা করে। আমরা কেবল কোড সরবরাহ না করেই শিক্ষিত করতে চাই।
টিন ম্যান

ট্রলপটির নামকরণ করা হয়েছে আশাবাদী github.com/manageiq/optimist । এছাড়াও এটি কেবলমাত্র একটি সিএলআই বিকল্প পার্সার যা প্রশ্নের উত্তর দেওয়ার দরকার নেই।
নুরজ

1

আপনার যদি লাইন সীমানা জুড়ে বিকল্পগুলি করতে হয়, তবে ব্যবহার করা কার্যকর ruby -pi -eহবে না কারণ pপ্রক্রিয়াগুলি একবারে এক লাইন প্রসেস করে। পরিবর্তে, আমি নিম্নলিখিতটি সুপারিশ করি, যদিও এটি মাল্টি-জিবি ফাইলের সাথে ব্যর্থ হতে পারে:

ruby -e "file='translation.ja.yml'; IO.write(file, (IO.read(file).gsub(/\s+'$/, %q('))))"

একটি শব্দের পরে শ্বেত স্থান (সম্ভাব্য নতুন লাইনগুলি সহ) অনুসন্ধান করা হচ্ছে, সেক্ষেত্রে এটি সাদা স্থান থেকে মুক্তি পাবে। %q(')উদ্ধৃতি চরিত্র উদ্ধৃত শুধু একটি অভিনব উপায়।


1

এখানে স্ক্রিপ্টে জিম থেকে এক লাইনারের বিকল্প

ARGV[0..-3].each{|f| File.write(f, File.read(f).gsub(ARGV[-2],ARGV[-1]))}

এটি কোনও স্ক্রিপ্টে সংরক্ষণ করুন, যেমন, edit.rb

আপনি কমান্ড লাইনে দিয়ে শুরু করুন

replace.rb *.txt <string_to_replace> <replacement>

* .txt অন্য নির্বাচন বা কিছু ফাইলের নাম বা পাথের সাথে প্রতিস্থাপন করা যেতে পারে

ভাঙ্গা যাতে আমি কী ঘটছে তা ব্যাখ্যা করতে পারি তবে এখনও কার্যকর হয়

# ARGV is an array of the arguments passed to the script.
ARGV[0..-3].each do |f| # enumerate the arguments of this script from the first to the last (-1) minus 2
  File.write(f,  # open the argument (= filename) for writing
    File.read(f) # open the argument (= filename) for reading
    .gsub(ARGV[-2],ARGV[-1])) # and replace all occurances of the beforelast with the last argument (string)
end

সম্পাদনা করুন: আপনি যদি নিয়মিত এক্সপ্রেশন ব্যবহার করতে চান তবে এর পরিবর্তে স্পষ্টতই, এটি কেবল তুলনামূলকভাবে ছোট পাঠ্য ফাইলগুলি পরিচালনা করার জন্য, কোনও গিগাবাইট দানব নয়

ARGV[0..-3].each{|f| File.write(f, File.read(f).gsub(/#{ARGV[-2]}/,ARGV[-1]))}

এই কোডটি কাজ করবে না। আমি পোস্ট করার আগে এটি পরীক্ষা করার পরামর্শ দেব, তারপরে ওয়ার্কিং কোডটি অনুলিপি করুন এবং আটকান।
টিন ম্যান

@ থিনমান আমি প্রকাশের আগে সর্বদা পরীক্ষা করি, যদি সম্ভব হয়। আমি এটি পরীক্ষা করে দেখেছি এবং এটি উভয়ই মন্তব্য করা সংস্করণ হিসাবে সংক্ষিপ্ত হিসাবে কাজ করে। আপনি কেন ভাবেন না কেন?
পিটার

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