2010-01-26 9 views
10

में एक स्ट्रिंग कैसे सम्मिलित करें मेरे पास एक कॉन्फ़िगरेशन फ़ाइल है जिसमें मैं एक स्ट्रिंग जोड़ना चाहता हूं, जो दिखता है उदा। इस तरह:एक टेक्स्टफाइल

line1 
line2 
line3 
line4 

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

file = File.open(path,"r+") 
while (!file.eof?) 
    line = file.readline 
    if (line.downcase.starts_with?("line1")) 
    file.write("Some nice little sentence") 
    end 
end 

समस्या यह है कि रूबी नए पाठ के साथ उस स्थिति में लाइन अधिलेखित कर देता है

line1 
Some nice little sentence 
line2 
line3 
line4 

यह कैसे प्राप्त किया जा सकता:

line1 
Some nice little sentence 
line3 
line4 

क्या मैं चाहता हूँ एक 'असली' शामिल करनी होगी: है, तो परिणाम पीछा कर रहा है?

उत्तर

11

यदि यह एक छोटे फ़ाइल है मुझे लगता है कि सबसे आसान तरीका होगा:

  • पूरी फाइल पढ़ें।
  • लाइन डालें।
  • नई फ़ाइल लिखें।

दृश्यों के पीछे Rails does it तरीका है।

या आप लाइन द्वारा लाइन यह कॉपी कर सकते हैं और फिर mv इस तरह के साथ मूल के ऊपर लिख:

require 'fileutils' 

tempfile=File.open("file.tmp", 'w') 
f=File.new("file.txt") 
f.each do |line| 
    tempfile<<line 
    if line.downcase=~/^line2/ 
    tempfile << "Some nice little sentence\n" 
    end 
end 
f.close 
tempfile.close 

FileUtils.mv("file.tmp", "file.txt") 
0

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

वैकल्पिक रूप से आप उस स्थान को पा सकते हैं जिसे आप रेखा डालना चाहते हैं, उस बिंदु के बाद लाइनों को स्मृति में पढ़ें, फ़ाइल में उस बिंदु पर वापस जाएं, फ़ाइल में अपनी नई पंक्ति लिखें, और अंत में शेष पंक्तियां लिखें फ़ाइल में। अगर आप फाइल का शेष बहुत बड़ा है तो फिर से आप समस्याओं में भाग लेंगे क्योंकि आपको इसे स्मृति में पढ़ना होगा।

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

फ़ाइल लेखन इस तरह काम करता है क्योंकि फ़ाइल बाइट्स के एक निश्चित आकार सरणी की तरह है: जब आप फ़ाइल में बाइट लिखते हैं तो आप एक मौजूदा बाइट को ओवरराइट कर देंगे (मैं उस मामले को अनदेखा कर रहा हूं जहां आप संलग्न करते हैं यहां एक फाइल)। इसलिए किसी फ़ाइल में कुछ भी सम्मिलित करने का एकमात्र तरीका पुरानी सामग्री को पुराने स्थान से पढ़कर और इसे नए स्थान पर लिखकर पहले किसी नए स्थान पर ले जाना है। उसके बाद आप अब रिक्त क्षेत्र में डेटा डाल सकते हैं।

4

एक जोड़े अन्य विकल्प:

file = File.read(path).sub(/line2\n/, 'Some nice little sentence\n\1') 
File.write(path, file) 

file = File.readlines(path) 
index = file.index("line2") 
file.insert(index, "Some nice little sentence") 
File.write(path, file) 
+0

मैंने इसका उपयोग करने की कोशिश की, लेकिन 'File.write (path,' w ')' फ़ाइल को एकल वर्ण 'w' के साथ ओवरराइट करता है - सही दृष्टिकोण क्या है? – dgmstuart

7
def replace(filepath, regexp, *args, &block) 
    content = File.read(filepath).gsub(regexp, *args, &block) 
    File.open(filepath, 'wb') { |file| file.write(content) } 
end 


replace(my_file, /^line2/mi) { |match| "Some nice little sentence"} 

line1 
Some nice little sentence 
line2 
line3 
line4 

और यदि आप संलग्न करना चाहते हैं मौजूदा ...

replace(my_file, /^line2/mi) do |match| 
    "#{match} Some nice little sentence" 
end 

line1 
line2 Some nice little sentence 
line2 
line3 
line4 
+0

मुझे यकीन है कि आपने पिछले उदाहरण में दो बार मुद्रित लाइन 2 को देखा है। – Magne

संबंधित मुद्दे

 संबंधित मुद्दे