मैं पायथन का उपयोग कर रहा हूं, और फ़ाइल को हटाने या कॉपी किए बिना एक टेक्स्ट फ़ाइल में एक स्ट्रिंग सम्मिलित करना चाहूंगा। मैं उसे कैसे कर सकता हूँ?
मैं पायथन का उपयोग कर रहा हूं, और फ़ाइल को हटाने या कॉपी किए बिना एक टेक्स्ट फ़ाइल में एक स्ट्रिंग सम्मिलित करना चाहूंगा। मैं उसे कैसे कर सकता हूँ?
जवाबों:
दुर्भाग्य से इसे दोबारा लिखे बिना किसी फाइल के बीच में डालने का कोई तरीका नहीं है। जैसा कि पिछले पोस्टरों ने संकेत दिया है, आप एक फ़ाइल या इसके एक हिस्से को अधिलेखित कर सकते हैं, लेकिन यदि आप शुरुआत या मध्य में सामान जोड़ना चाहते हैं, तो आपको इसे फिर से लिखना होगा।
यह एक ऑपरेटिंग सिस्टम चीज़ है, पायथन चीज़ नहीं। यह सभी भाषाओं में समान है।
मैं आमतौर पर फ़ाइल से पढ़ता हूं, संशोधन करता हूं और इसे एक नई फ़ाइल पर लिखता हूं जिसे myfile.txt.tmp या उसके बाद कुछ कहा जाता है। यह पूरी फ़ाइल को मेमोरी में पढ़ने से बेहतर है क्योंकि फ़ाइल उसके लिए बहुत बड़ी हो सकती है। एक बार अस्थायी फ़ाइल पूरी हो जाने के बाद, मैं इसे मूल फ़ाइल के समान नाम देता हूँ।
यह करने का एक अच्छा, सुरक्षित तरीका है क्योंकि यदि फ़ाइल किसी कारण से क्रैश या एबॉर्ट्स लिखती है, तो आपके पास अभी भी आपकी अछूता मूल फ़ाइल है।
निर्भर करता है कि आपकी क्या करने की इच्छा है। संलग्न करने के लिए आप इसे "ए" के साथ खोल सकते हैं:
with open("foo.txt", "a") as f:
f.write("new line\n")
यदि आप पहले फ़ाइल से कुछ पढ़ना चाहते हैं, तो:
with open("foo.txt", "r+") as f:
old = f.read() # read everything in the file
f.seek(0) # rewind
f.write("new line\n" + old) # write the new line before
with
पायथन 2.5 में बयान का उपयोग करने के लिए आपको " भविष्य के आयात के साथ_स्टैटमेंट" से जोड़ना होगा । इसके अलावा, with
बयान के साथ फाइलें खोलना निश्चित रूप से अधिक पठनीय है और मैन्युअल समापन की तुलना में कम त्रुटि वाला है।
fileinput
सहायक को गंदे खुले / पढ़ने / संशोधित / लिखने / नियमित रूप से inline=True
आरजी का उपयोग करते समय प्रतिस्थापित करने के साथ काम करने पर विचार कर सकते हैं । यहाँ उदाहरण: stackoverflow.com/a/2363893/47390
f.Close()
fileinput
यदि आप inplace = 1 पैरामीटर का उपयोग करते हैं, तो पायथन मानक लाइब्रेरी का मॉड्यूल एक फ़ाइल इनाइल को फिर से लिखेगा।
import sys
import fileinput
# replace all occurrences of 'sit' with 'SIT' and insert a line after the 5th
for i, line in enumerate(fileinput.input('lorem_ipsum.txt', inplace=1)):
sys.stdout.write(line.replace('sit', 'SIT')) # replace 'sit' and write
if i == 4: sys.stdout.write('\n') # write a blank line after the 5th line
एक जगह पर एक फ़ाइल को फिर से लिखना अक्सर पुरानी कॉपी को संशोधित नाम के साथ सहेज कर किया जाता है। यूनिक्स लोग ~
पुराने को चिह्नित करने के लिए एक जोड़ते हैं । विंडोज के लोग सभी प्रकार की चीजें करते हैं - .bak या .old जोड़ें - या पूरी तरह से फ़ाइल का नाम बदलें या नाम के सामने ~ डाल दें।
import shutil
shutil.move( afile, afile+"~" )
destination= open( aFile, "w" )
source= open( aFile+"~", "r" )
for line in source:
destination.write( line )
if <some condition>:
destination.write( >some additional line> + "\n" )
source.close()
destination.close()
इसके बजाय shutil
, आप निम्न का उपयोग कर सकते हैं।
import os
os.rename( aFile, aFile+"~" )
os.rename(aFile, aFile + "~")
स्रोत फ़ाइल का नाम संशोधित करेगा, प्रतिलिपि नहीं बना रहा है।
पायथन का mmap मॉड्यूल आपको एक फ़ाइल में सम्मिलित करने की अनुमति देगा। निम्न नमूना दिखाता है कि यह यूनिक्स में कैसे किया जा सकता है (विंडोज मिमीप अलग हो सकता है)। ध्यान दें कि यह सभी त्रुटि स्थितियों को संभालता नहीं है और आप मूल फ़ाइल को दूषित या खो सकते हैं। इसके अलावा, यह यूनिकोड स्ट्रिंग्स को हैंडल नहीं करेगा।
import os
from mmap import mmap
def insert(filename, str, pos):
if len(str) < 1:
# nothing to insert
return
f = open(filename, 'r+')
m = mmap(f.fileno(), os.path.getsize(filename))
origSize = m.size()
# or this could be an error
if pos > origSize:
pos = origSize
elif pos < 0:
pos = 0
m.resize(origSize + len(str))
m[pos+len(str):] = m[pos:origSize]
m[pos:pos+len(str)] = str
m.close()
f.close()
यह बिना संभव नहीं है कि बिना mmap के भी 'r +' मोड में खोली गई फ़ाइलों के साथ, लेकिन यह कम सुविधाजनक और कम कुशल है क्योंकि आपको फ़ाइल की सामग्री को प्रविष्टि स्थिति से EOF में अस्थायी रूप से पढ़ना और स्टोर करना होगा - जो हो सकता है विशाल होना।
जैसा कि एडम ने उल्लेख किया है कि आपको दृष्टिकोण पर निर्णय लेने से पहले अपनी प्रणाली की सीमाओं को ध्यान में रखना होगा कि क्या आपके पास यह सब पढ़ने के लिए पर्याप्त मेमोरी है या नहीं और इसे फिर से लिखना है।
यदि आप एक छोटी फ़ाइल के साथ काम कर रहे हैं या कोई स्मृति समस्या नहीं है तो यह मदद कर सकता है:
विकल्प 1) पूरी फ़ाइल को मेमोरी में पढ़ें, लाइन के पूरे या भाग पर एक रेगेक्स प्रतिस्थापन करें और इसे उस लाइन के साथ बदलें और अतिरिक्त लाइन। आपको यह सुनिश्चित करने की आवश्यकता होगी कि फ़ाइल में 'मध्य रेखा' अद्वितीय है या यदि आपके पास प्रत्येक पंक्ति पर टाइमस्टैम्प है तो यह बहुत विश्वसनीय होना चाहिए।
# open file with r+b (allow write and binary mode)
f = open("file.log", 'r+b')
# read entire content of file into memory
f_content = f.read()
# basically match middle line and replace it with itself and the extra line
f_content = re.sub(r'(middle line)', r'\1\nnew line', f_content)
# return pointer to top of file so we can re-write the content with replaced string
f.seek(0)
# clear file content
f.truncate()
# re-write the content with the updated content
f.write(f_content)
# close file
f.close()
विकल्प 2) मध्य रेखा का पता लगाएं, और इसे उस रेखा के साथ बदलें और अतिरिक्त रेखा।
# open file with r+b (allow write and binary mode)
f = open("file.log" , 'r+b')
# get array of lines
f_content = f.readlines()
# get middle line
middle_line = len(f_content)/2
# overwrite middle line
f_content[middle_line] += "\nnew line"
# return pointer to top of file so we can re-write the content with replaced string
f.seek(0)
# clear file content
f.truncate()
# re-write the content with the updated content
f.write(''.join(f_content))
# close file
f.close()
इसे सफाई से करने के लिए एक छोटा वर्ग लिखा।
import tempfile
class FileModifierError(Exception):
pass
class FileModifier(object):
def __init__(self, fname):
self.__write_dict = {}
self.__filename = fname
self.__tempfile = tempfile.TemporaryFile()
with open(fname, 'rb') as fp:
for line in fp:
self.__tempfile.write(line)
self.__tempfile.seek(0)
def write(self, s, line_number = 'END'):
if line_number != 'END' and not isinstance(line_number, (int, float)):
raise FileModifierError("Line number %s is not a valid number" % line_number)
try:
self.__write_dict[line_number].append(s)
except KeyError:
self.__write_dict[line_number] = [s]
def writeline(self, s, line_number = 'END'):
self.write('%s\n' % s, line_number)
def writelines(self, s, line_number = 'END'):
for ln in s:
self.writeline(s, line_number)
def __popline(self, index, fp):
try:
ilines = self.__write_dict.pop(index)
for line in ilines:
fp.write(line)
except KeyError:
pass
def close(self):
self.__exit__(None, None, None)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
with open(self.__filename,'w') as fp:
for index, line in enumerate(self.__tempfile.readlines()):
self.__popline(index, fp)
fp.write(line)
for index in sorted(self.__write_dict):
for line in self.__write_dict[index]:
fp.write(line)
self.__tempfile.close()
तो आप इसे इस तरह से उपयोग कर सकते हैं:
with FileModifier(filename) as fp:
fp.writeline("String 1", 0)
fp.writeline("String 2", 20)
fp.writeline("String 3") # To write at the end of the file
यदि आप कुछ यूनिक्स जानते हैं, तो आप निम्नलिखित प्रयास कर सकते हैं:
नोट: $ का अर्थ है कमांड प्रॉम्प्ट
कहो कि आपके पास ऐसी सामग्री के साथ एक फ़ाइल my_data.txt है:
$ cat my_data.txt
This is a data file
with all of my data in it.
फिर os
मॉड्यूल का उपयोग करके आप सामान्य sed
कमांड का उपयोग कर सकते हैं
import os
# Identifiers used are:
my_data_file = "my_data.txt"
command = "sed -i 's/all/none/' my_data.txt"
# Execute the command
os.system(command)
अगर आपको सेड के बारे में जानकारी नहीं है, तो इसे देखें, यह बेहद उपयोगी है।