एक पैटर्न के लिए फ़ाइल टेक्स्ट कैसे खोजें और इसे दिए गए मान से बदलें


117

मैं एक पैटर्न के लिए एक फ़ाइल (या फ़ाइलों की सूची) की खोज करने के लिए एक स्क्रिप्ट की तलाश कर रहा हूं और यदि पाया जाता है, तो उस पैटर्न को दिए गए मान के साथ बदलें।

विचार?


1
नीचे दिए गए जवाबों में, ध्यान रखें कि बड़ी फ़ाइलों को खराब करने के लिए किसी भी सिफारिशें का उपयोग File.readकरने के लिए stackoverflow.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.open (file_name, "w") लिखने के लिए {| फ़ाइल | file.puts output_of_gsub}
मैक्स

7
मुझे file.write: File.open (file_name, "w") {| file | का उपयोग करना था
file.write

3
लिखने फ़ाइल करने के लिए, के साथ कहते हैं 'लाइन की जगहFile.write(file_name, text.gsub(/regexp/, "replace")
तंग

106

दरअसल, रूबी के पास इन-प्लेस एडिटिंग फीचर है। पर्ल की तरह, आप कह सकते हैं

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

यह वर्तमान निर्देशिका में उन सभी फ़ाइलों के लिए दोहरे-उद्धरणों में कोड लागू करेगा, जिनके नाम ".txt" के साथ समाप्त होते हैं। संपादित फ़ाइलों की बैकअप प्रतियां ".bak" एक्सटेंशन ("foobar.txt.bak" मुझे लगता है) के साथ बनाई जाएंगी।

नोट: यह मल्टीलाइन खोजों के लिए काम नहीं करता है। उन लोगों के लिए, आपको इसे अन्य कम सुंदर तरीके से करना होगा, रेगेक्स के चारों ओर एक आवरण स्क्रिप्ट के साथ।


1
बिल्ली क्या है pi.bak? उसके बिना, मुझे एक त्रुटि मिलती है। -e: 1: <main>': undefined method gsub में मुख्य के लिए: ऑब्जेक्ट (NoMethodError)
निनाद

15
@NinadPachpute -iजगह-जगह संपादन करता है। .bakबैकअप फ़ाइल (वैकल्पिक) के लिए उपयोग किया जाने वाला एक्सटेंशन है। -pकी तरह कुछ है while gets; <script>; puts $_; end। ( $_अंतिम पठन पंक्ति है, लेकिन आप इसे कुछ इस तरह से असाइन कर सकते हैं echo aa | ruby -p -e '$_.upcase!'।)
लारी

1
यदि आप फ़ाइल को संशोधित करना चाहते हैं, तो यह स्वीकृत उत्तर, IMHO से बेहतर उत्तर है।
कॉलिन के

6
मैं रूबी लिपि के अंदर इसका उपयोग कैसे कर सकता हूं ??
सौरभ

1
ऐसे कई तरीके हैं जो गलत हो सकते हैं इसलिए किसी महत्वपूर्ण फाइल के खिलाफ प्रयास करने से पहले इसे अच्छी तरह से परख लें।
टीन मैन

49

ध्यान रखें कि, जब आप ऐसा करते हैं, तो फ़ाइल सिस्टम अंतरिक्ष से बाहर हो सकता है और आप एक शून्य-लंबाई फ़ाइल बना सकते हैं। यदि आप सिस्टम कॉन्फ़िगरेशन प्रबंधन के भाग के रूप में बाहर / etc / passwd फ़ाइलों को लिखने जैसा कुछ कर रहे हैं तो यह भयावह है।

ध्यान दें कि स्वीकार किए गए उत्तर की तरह इन-प्लेस फ़ाइल संपादन हमेशा फ़ाइल को छोटा करेगा और क्रमिक रूप से नई फ़ाइल लिखेगा। हमेशा एक दौड़ की स्थिति होगी जहां समवर्ती पाठकों को एक छंटनी की गई फ़ाइल दिखाई देगी। यदि लिखने के दौरान किसी भी कारण (ctrl-c, OOM हत्यारा, सिस्टम क्रैश, पावर आउटेज, आदि) के लिए प्रक्रिया को रद्द कर दिया जाता है, तो छंटनी की गई फ़ाइल को भी छोड़ दिया जाएगा, जो भयावह हो सकती है। यह एक प्रकार का डलाटॉस परिदृश्य है जिसे डेवलपर्स जरूरी मानते हैं क्योंकि यह होगा। उस कारण से, मुझे लगता है कि स्वीकृत उत्तर को स्वीकार किए जाने वाले उत्तर में नहीं होना चाहिए। एक नंगे न्यूनतम लिखने के लिए एक अस्थायी और इस उत्तर के अंत में "सरल" समाधान की तरह फ़ाइल को स्थानांतरित / स्थानांतरित करें।

आपको एक एल्गोरिथ्म का उपयोग करने की आवश्यकता है जो:

  1. पुरानी फ़ाइल पढ़ता है और नई फ़ाइल को लिखता है। (आपको संपूर्ण फ़ाइलों को मेमोरी में खिसकने से सावधान रहने की आवश्यकता है)।

  2. स्पष्ट रूप से नई अस्थायी फ़ाइल को बंद कर देता है, जो कि आप एक अपवाद फेंक सकते हैं क्योंकि फ़ाइल बफ़र्स को डिस्क पर नहीं लिखा जा सकता क्योंकि कोई स्थान नहीं है। (इसे पकड़ें और यदि आप चाहें, तो अस्थायी फ़ाइल को साफ़ करें, लेकिन आपको इस बिंदु पर कुछ पुनर्विचार करने या असफल होने की आवश्यकता है।

  3. नई फ़ाइल पर फ़ाइल अनुमतियाँ और मोड को ठीक करता है।

  4. नई फ़ाइल का नाम बदलता है और इसे जगह में छोड़ देता है।

Ext3 फाइल सिस्टम के साथ आपको गारंटी दी जाती है कि फ़ाइल को स्थानांतरित करने के लिए मेटाडेटा फ़ाइल सिस्टम द्वारा पुनर्व्यवस्थित नहीं होगा और नई फ़ाइल के लिए डेटा बफ़र्स लिखे जाने से पहले लिखा गया है, इसलिए यह या तो सफल होना चाहिए या विफल होना चाहिए। इस तरह के व्यवहार का समर्थन करने के लिए ext4 फाइलसिस्टम को भी पैच किया गया है। यदि आप बहुत अधिक पागल हैं, तो आपको fdatasync()फ़ाइल को जगह में ले जाने से पहले चरण 3.5 के रूप में सिस्टम कॉल को कॉल करना चाहिए ।

भाषा के बावजूद, यह सबसे अच्छा अभ्यास है। उन भाषाओं में जहां कॉलिंग close()एक अपवाद को नहीं फेंकती है (पर्ल या सी) आपको स्पष्ट रूप से वापसी की जांच करनी चाहिए close()और अगर यह विफल हो जाता है तो अपवाद को फेंक दें।

ऊपर दिए गए सुझाव को फ़ाइल को केवल मेमोरी में खिसकाना, इसमें हेरफेर करना और इसे फ़ाइल में लिखना एक पूर्ण फाइलसिस्टम पर शून्य-लंबाई फ़ाइलों का उत्पादन करने की गारंटी होगी। आपको हमेशा उपयोग करने की आवश्यकता हैFileUtils.mv एक पूरी तरह से लिखित अस्थायी फ़ाइल को जगह में स्थानांतरित करने के लिए करने है।

एक अंतिम विचार अस्थायी फ़ाइल की नियुक्ति है। यदि आप / tmp में एक फ़ाइल खोलते हैं तो आपको कुछ समस्याओं पर विचार करना होगा:

  • यदि / tmp किसी भिन्न फ़ाइल सिस्टम पर आरूढ़ है, तो इससे पहले कि आप उस फ़ाइल को लिखे, जिसे अन्यथा पुरानी फ़ाइल के गंतव्य के लिए लागू किया जाएगा।

  • संभवतः अधिक महत्वपूर्ण बात यह है कि जब आप mvडिवाइस माउंट करने की कोशिश करेंगे तो आप पारदर्शी रूप से cpव्यवहार में परिवर्तित हो जाएंगे । पुरानी फ़ाइल को खोला जाएगा, पुरानी फ़ाइलों को इनकोड संरक्षित किया जाएगा और फिर से खोला जाएगा और फ़ाइल सामग्री की प्रतिलिपि बनाई जाएगी। यह सबसे अधिक संभावना है कि आप क्या चाहते हैं, और आप "पाठ फ़ाइल व्यस्त" त्रुटियों में चला सकते हैं यदि आप किसी चल रही फ़ाइल की सामग्री को संपादित करने का प्रयास करते हैं। यह फाइलसिस्टम mvकमांड का उपयोग करने के उद्देश्य को भी पराजित करता है और आप केवल आंशिक रूप से लिखित फाइल के साथ गंतव्य फाइल सिस्टम को अंतरिक्ष से बाहर चला सकते हैं।

    यह भी रूबी के कार्यान्वयन से कोई लेना-देना नहीं है। सिस्टम mvऔर cpकमांड समान व्यवहार करते हैं।

पुरानी फ़ाइल के रूप में एक ही निर्देशिका में एक Tempfile खोलने के लिए अधिक बेहतर है। यह सुनिश्चित करता है कि कोई क्रॉस-डिवाइस चालित समस्याएं नहीं होंगी। mvखुद असफल कभी नहीं करना चाहिए, और आप हमेशा एक पूर्ण और untruncated फ़ाइल मिलना चाहिए। किसी भी विफलताओं, जैसे कि अंतरिक्ष से बाहर उपकरण, अनुमति त्रुटियां, इत्यादि का सामना करना चाहिए, जो कि टेंपफाइल आउट लिखने के दौरान किया जाना चाहिए।

गंतव्य निर्देशिका में Tempfile बनाने के दृष्टिकोण में केवल निम्न हैं:

  • कभी-कभी आप वहां एक टेंपाइल नहीं खोल सकते हैं, जैसे कि आप उदाहरण के लिए / proc फ़ाइल को 'संपादित' करने का प्रयास कर रहे हैं। उस कारण से आप वापस गिरना चाहते हैं और गंतव्य निर्देशिका में फ़ाइल खोलने में विफल होने पर कोशिश / tmp कर सकते हैं।
  • पूर्ण पुरानी फ़ाइल और नई फ़ाइल दोनों को रखने के लिए आपके पास गंतव्य विभाजन पर पर्याप्त स्थान होना चाहिए। हालाँकि, यदि आपके पास दोनों प्रतियों को रखने के लिए अपर्याप्त स्थान है तो आप शायद डिस्क स्थान पर कम हैं और एक छंटनी की गई फ़ाइल को लिखने का वास्तविक जोखिम बहुत अधिक है, इसलिए मेरा तर्क है कि यह कुछ अत्यधिक संकीर्ण (संकीर्ण और अच्छी तरह से बाहर एक बहुत खराब ट्रेडऑफ़ है) -समारोहित) किनारे के मामले।

यहाँ कुछ कोड है जो पूर्ण-एल्गोरिथ्म को लागू करता है (विंडोज़ कोड अप्राप्त और अपूर्ण है):

#!/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")

टीएल; डीआर : इसका उपयोग कम से कम स्वीकृत उत्तर के बजाय सभी मामलों में किया जाना चाहिए, ताकि यह सुनिश्चित हो सके कि अद्यतन परमाणु है और समवर्ती पाठकों को छंटनी की गई फाइलें नहीं दिखाई देंगी। जैसा कि मैंने ऊपर उल्लेख किया है, संपादित फ़ाइल के रूप में एक ही निर्देशिका में Tempfile बनाना यहाँ क्रॉस डिवाइस mv संचालन cp संचालन में अनुवादित होने से बचने के लिए महत्वपूर्ण है अगर / tmp को किसी भिन्न डिवाइस पर आरोहित किया जाता है। Fdatasync को कॉल करना व्यामोह की एक अतिरिक्त परत है, लेकिन यह एक प्रदर्शन हिट को प्रभावित करेगा, इसलिए मैंने इसे इस उदाहरण से छोड़ दिया क्योंकि यह आमतौर पर प्रचलित नहीं है।


निर्देशिका में एक अस्थायी फ़ाइल खोलने के बजाय, आप वास्तव में इसमें स्वचालित रूप से ऐप डेटा निर्देशिका (विंडोज वैसे भी) में एक बना देंगे और उनकी ओर से आप इसे हटाने के लिए एक फ़ाइल कर सकते हैं।
13aal

3
मैंने वास्तव में उस अतिरिक्त विचार की सराहना की जो इसमें डाला गया था। एक शुरुआत के रूप में, अनुभवी देवों के विचार पैटर्न को देखना बहुत दिलचस्प है, जो न केवल मूल प्रश्न का उत्तर दे सकते हैं, बल्कि इस बात के बड़े संदर्भ पर भी टिप्पणी कर सकते हैं कि मूल प्रश्न का वास्तव में क्या मतलब है।
रामजीम

प्रोग्रामिंग तत्काल समस्या को ठीक करने के बारे में नहीं है, यह प्रतीक्षा में पड़ी अन्य समस्याओं से बचने के लिए आगे सोचने के तरीके के बारे में भी है। कुछ भी नहीं एक वरिष्ठ डेवलपर को एनकाउंटर कोड से अधिक परेशान करता है जिसने एल्गोरिथ्म को एक कोने में चित्रित किया, एक अजीब कीचड़ के लिए मजबूर किया, जब पहले से मामूली समायोजन के परिणामस्वरूप एक अच्छा प्रवाह होगा। लक्ष्य को समझने के लिए विश्लेषण करने में अक्सर घंटों या दिनों का समय लग सकता है, और फिर कुछ पंक्तियाँ पुराने कोड के एक पेज को बदल देती हैं। यह कई बार डेटा और सिस्टम के खिलाफ शतरंज के खेल की तरह है।
द टिन मैन

11

वास्तव में इन-फाइल्स को संपादित करने का कोई तरीका नहीं है। जब आप इसे दूर कर सकते हैं तो आप आमतौर पर क्या करते हैं (यानी यदि फाइलें बहुत बड़ी नहीं हैं), तो आप फ़ाइल को मेमोरी में पढ़ें ( File.read), रीड स्ट्रिंग पर अपने प्रतिस्थापन का प्रदर्शन करें ( String#gsub) और फिर बदले हुए स्ट्रिंग को वापस लिखें। फ़ाइल ( File.open, File#write)।

आप उपयोग कर सकते हैं - फ़ाइलें बहुत बड़ी है कि अव्यावहारिक होने के लिए, आप क्या करने की जरूरत है, तो मात्रा में फ़ाइल को पढ़ने (यदि पैटर्न आप को बदलने के लिए कई पंक्तियों अवधि नहीं होगा तो एक हिस्सा आमतौर पर एक पंक्ति का अर्थ है चाहता हूँ File.foreachके लिए एक फ़ाइल लाइन को लाइन से पढ़ें), और प्रत्येक चंक के लिए उस पर प्रतिस्थापन का प्रदर्शन करें और इसे एक अस्थायी फ़ाइल में जोड़ें। जब आप स्रोत फ़ाइल पर पुनरावृत्ति कर रहे हैं, तो आप इसे बंद कर देते हैं और FileUtils.mvअस्थायी फ़ाइल के साथ इसे अधिलेखित करने के लिए उपयोग करते हैं।


1
मुझे स्ट्रीमिंग का तरीका पसंद है। हम बड़ी फ़ाइलों के साथ समवर्ती रूप से निपटते हैं, इसलिए हमारे पास आमतौर पर रैम में पूरी फाइल पढ़ने के लिए जगह नहीं होती है
शेन

" क्यों एक अच्छा अभ्यास नहीं है" एक फाइल "slurping" है? इस के संबंध में उपयोगी पढ़ने हो सकता है।
टीन मैन

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फ़ाइल को स्लूर ( ) करने की कोशिश करने से बेहतर होगा । यह स्केलेबल है और बहुत तेज होना चाहिए।
टीन मैन

अगर एक ही फ़ाइल पर कई लगातार inplace_edit ब्लॉक हैं, तो अनुमति देने में विफल रहने के कारण विंडोज पर रूबी 2.3.0p0 के कारण एक बग है। 2 ब्लॉक में विभाजित search1 और search2 परीक्षणों को पुन: उत्पन्न करने के लिए। पूरी तरह से बंद नहीं?
21

मुझे एक साथ होने वाली एक पाठ फ़ाइल के कई संपादन के साथ समस्याओं की उम्मीद होगी। यदि और कुछ नहीं तो आप एक बुरी तरह से उलझी हुई पाठ फ़ाइल प्राप्त कर सकते हैं।
द टीन मैन

7

यह मेरे लिए काम करता है:

filename = "foo"
text = File.read(filename) 
content = text.gsub(/search_regexp/, "replacestring")
File.open(filename, "w") { |file| file << content }

6

यहां दिए गए डायरेक्टरी की सभी फाइलों को खोजने / बदलने का एक समाधान है। मूल रूप से मैंने sepp2k द्वारा प्रदान किया गया उत्तर लिया और इसका विस्तार किया।

# 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 कर दिया गया । इसके अलावा यह सिर्फ एक CLI विकल्प पार्सर है जिसे वास्तव में प्रश्न का उत्तर देने की आवश्यकता नहीं है।
नूरज

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

इसे स्क्रिप्ट में सेव करें, जैसे रिप्लेस.आरबी

आप कमांड लाइन पर शुरू करते हैं

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

यह कोड काम नहीं करेगा। मेरा सुझाव है कि पोस्ट करने से पहले इसका परीक्षण करें, फिर वर्किंग कोड को कॉपी और पेस्ट करें।
टिन मैन

@TinMan मैं हमेशा प्रकाशन से पहले परीक्षण करता हूं, यदि संभव हो तो। मैंने यह परीक्षण किया है और यह टिप्पणी की गई संस्करण के रूप में दोनों काम करता है। आपको क्यों लगता है कि यह नहीं होगा?
पीटर

यदि आप का उपयोग कर एक रेगुलर एक्सप्रेशन मेरे संपादित देख मतलब है, इस पर जांच की:>)
पीटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.