Python kullanıyorum ve dosyayı silmeden veya kopyalamadan bir metin dosyasına bir dize eklemek istiyorum. Bunu nasıl yapabilirim?
Python kullanıyorum ve dosyayı silmeden veya kopyalamadan bir metin dosyasına bir dize eklemek istiyorum. Bunu nasıl yapabilirim?
Yanıtlar:
Ne yazık ki bir dosyayı yeniden yazmadan ortasına yerleştirmenin bir yolu yoktur. Önceki posterlerin de belirttiği gibi, bir dosyaya ekleyebilir veya aramanın bir kısmını üzerine yazabilirsiniz, ancak başında veya ortasında bir şeyler eklemek istiyorsanız, yeniden yazmanız gerekir.
Bu bir işletim sistemi şeyidir, Python değil. Tüm dillerde aynıdır.
Genellikle yaptığım dosyadan okumak, değişiklikleri yapmak ve myfile.txt.tmp adlı yeni bir dosyaya ya da buna benzer bir dosyaya yazmak. Bu, tüm dosyayı belleğe okumaktan daha iyidir çünkü dosya bunun için çok büyük olabilir. Geçici dosya tamamlandığında, orijinal dosya ile aynı şekilde yeniden adlandırıyorum.
Bu, dosya yazma işlemi herhangi bir nedenle çökerse veya iptal edilirse, el değmemiş orijinal dosyanızın olması nedeniyle bunu yapmanın iyi ve güvenli bir yoludur.
Ne yapmak istediğine bağlı. Eklemek için "a" ile açabilirsiniz:
with open("foo.txt", "a") as f:
f.write("new line\n")
Öncelikle dosyadan okumak zorunda olduğunuz bir şeyi önceden eklemek istiyorsanız:
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
Python 2.5 deyimini kullanmak için " gelecekteki ithalat ile_statement gelen" eklemeniz gerekir . Bunun dışında, with
ifadeyle dosyaları açmak kesinlikle manuel olarak okunmaktan daha okunaklı ve daha az hataya açıktır.
fileinput
Arg kullanırken kirli lib / okuma / değiştirme / yazma / değiştirme rutinini güzel bir şekilde ele alan yardımcı lib'i düşünebilirsiniz inline=True
. Burada örnek: stackoverflow.com/a/2363893/47390
f.Close()
fileinput
Eğer INPLACE = 1 parametresini kullanırsanız Python standart kütüphanenin modül dosya INPLACE tekrar sunacağına:
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
Bir dosyayı yerinde yeniden yazmak genellikle eski kopyanın değiştirilmiş bir adla kaydedilmesiyle yapılır. Unix kullanıcıları ~
eskisini işaretlemek için a ekler . Windows kullanıcıları her türlü şeyi yapar - .bak veya .old - ekleyin veya dosyayı tamamen yeniden adlandırın veya ~ adının önüne koyun.
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()
Bunun yerine shutil
aşağıdakileri kullanabilirsiniz.
import os
os.rename( aFile, aFile+"~" )
os.rename(aFile, aFile + "~")
kaynak dosyanın adını değiştirir, kopya oluşturmaz.
Python'un mmap modülü bir dosyaya eklemenizi sağlar. Aşağıdaki örnek Unix'te nasıl yapılabileceğini göstermektedir (Windows mmap farklı olabilir). Bunun tüm hata koşullarını karşılamadığını ve orijinal dosyayı bozabileceğinizi veya kaybedebileceğinizi unutmayın. Ayrıca, bu unicode dizeleri işlemez.
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()
Bunu, 'r +' modunda açılan dosyalar ile mmap olmadan da yapmak mümkündür, ancak dosyanın içeriğini ekleme konumundan EOF'a geçici olarak okumak ve depolamak zorunda olduğunuz için daha az kullanışlı ve daha az verimlidir. büyük ol.
Adam'ın belirttiği gibi, hepsini belleğe okumak için yeterli belleğe sahip olup olmadığına ve yeniden yazıp yazmayacağınıza karar vermeden önce sistem sınırlamalarınızı dikkate almanız gerekir.
Küçük bir dosyayla uğraşıyorsanız veya bellek sorununuz yoksa bu yardımcı olabilir:
Seçenek 1) Dosyanın tamamını belleğe okuyun, satırın tamamı veya bir bölümünde normal ifade yerine koyma yapın ve bu satırla birlikte ekstra satırla değiştirin. 'Orta çizginin' dosyada benzersiz olduğundan emin olmanız gerekir veya her satırda zaman damgalarınız varsa bu oldukça güvenilir olmalıdır.
# 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()
Seçenek 2) Orta çizgiyi bulun ve bu çizgiyle artı ekstra çizgiyle değiştirin.
# 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()
Bunu temiz yapmak için küçük bir sınıf yazdı.
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()
Sonra bu şekilde kullanabilirsiniz:
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
Bazı unix biliyorsanız aşağıdakileri deneyebilirsiniz:
Notlar: $, komut istemi anlamına gelir
Diyelim ki böyle içerik içeren bir my_data.txt dosyanız var:
$ cat my_data.txt
This is a data file
with all of my data in it.
Sonra os
modülü kullanarak olağan sed
komutları kullanabilirsiniz.
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)
Sed'in farkında değilseniz, göz atın, son derece yararlıdır.