Python'da metin dosyasındaki belirli satırı düzenleme


88

Diyelim ki şunu içeren bir metin dosyam var:

Dan
Warrior
500
1
0

O metin dosyasındaki belirli bir satırı düzenlememin bir yolu var mı? Şu anda bu var:

#!/usr/bin/env python
import io

myfile = open('stats.txt', 'r')
dan = myfile.readline()
print dan
print "Your name: " + dan.split('\n')[0]

try:
    myfile = open('stats.txt', 'a')
    myfile.writelines('Mage')[1]
except IOError:
        myfile.close()
finally:
        myfile.close()

Evet, myfile.writelines('Mage')[1]bunun yanlış olduğunu biliyorum . Ama demek istediğimi anladın, değil mi? Warrior'u Mage ile değiştirerek 2. satırı düzenlemeye çalışıyorum. Ama bunu yapabilir miyim?


1
Sanırım bu gönderi aradığınız şeyi kapsıyor: stackoverflow.com/questions/1998233/…
Kyle Wild

1
Bu tür şeyleri çok yapmak zorundaysanız, bu dosyayı metinden bdb veya diğer bdb benzeri bir şeye dönüştürmek isteyebilirsiniz.
Nick Bastin

Yanıtlar:


125

Bunun gibi bir şey yapmak istiyorsun:

# with is like your try .. finally block in this case
with open('stats.txt', 'r') as file:
    # read a list of lines into data
    data = file.readlines()

print data
print "Your name: " + data[0]

# now change the 2nd line, note that you have to add a newline
data[1] = 'Mage\n'

# and write everything back
with open('stats.txt', 'w') as file:
    file.writelines( data )

Bunun nedeni, "2. satırı değiştir" gibi bir şeyi doğrudan bir dosyada yapamamanızdır. Bir dosyanın yalnızca bazı bölümlerinin üzerine yazabilirsiniz (silemezsiniz) - bu, yeni içeriğin yalnızca eski içeriği kapsadığı anlamına gelir. Öyleyse, 2. satırın üzerine 'Mage' yazarsanız, ortaya çıkan satır 'Mageior' olacaktır.


2
Merhaba Jochen, "with open (dosya adı, mod)" ifadesi de program çıktıktan sonra dosya adını örtük olarak kapatır, değil mi?
Radu

@Gabriel Thx, not etmek önemli, ancak yine de with ... 'i dosya ifadesi olarak kullanmıyorum. Pythonic ya da değil, beğenmedim :)
Radu

@Radu buna alışma meselesi. Ayrıca açılan dosyaları manuel olarak kapatırdım close.ama şimdi bir withblok kullanmanın çok daha temiz olduğunu görüyorum .
Gabriel

5
Bunun küçük dosyalar için tercih edilen bir çözüm olduğunu varsaymak doğru mu? Aksi takdirde, verileri depolamak için çok fazla belleğe ihtiyacımız olabilir. Üstelik 1 düzenleme için bile her şeyi yeniden yazmamız gerekiyor.
Arindam Roychowdhury

11
Kötü .. 20 Gb dosyanız varsa ne olur?
Brans Ds

21

yerinde düzenleme yapmak için fileinput'u kullanabilirsiniz

import fileinput
for  line in fileinput.FileInput("myfile", inplace=1):
    if line .....:
         print line

19
def replace_line(file_name, line_num, text):
    lines = open(file_name, 'r').readlines()
    lines[line_num] = text
    out = open(file_name, 'w')
    out.writelines(lines)
    out.close()

Ve sonra:

replace_line('stats.txt', 0, 'Mage')

9
bu, dosyanın tüm içeriğini belleğe yükler ve bu dosya çok büyükse iyi bir şey olmayabilir.
Steve Ng

@SteveNg fark ettiğiniz sorun için bir çözümünüz var mı? hem bu yanıt hem de kabul edilen yanıt, tüm dosyanın belleğe yüklenmesine güveniyor
Blupon

14

Bunu iki şekilde yapabilirsiniz, ihtiyacınıza uygun olanı seçin:

Yöntem I.) Satır numarasını kullanarak değiştirme. enumerate()Bu durumda yerleşik işlevi kullanabilirsiniz :

İlk olarak, okuma modunda bir değişkendeki tüm verileri alın

with open("your_file.txt",'r') as f:
    get_all=f.readlines()

İkinci olarak, dosyaya yazın ( numaralandırmanın devreye girdiği yer )

with open("your_file.txt",'w') as f:
    for i,line in enumerate(get_all,1):         ## STARTS THE NUMBERING FROM 1 (by default it begins with 0)    
        if i == 2:                              ## OVERWRITES line:2
            f.writelines("Mage\n")
        else:
            f.writelines(line)

Yöntem II.) Değiştirmek istediğiniz anahtar kelimeyi kullanarak:

Dosyayı okuma modunda açın ve içeriğini bir listeye kopyalayın

with open("some_file.txt","r") as f:
    newline=[]
    for word in f.readlines():        
        newline.append(word.replace("Warrior","Mage"))  ## Replace the keyword while you copy.  

"Savaşçı", "Büyücü" ile değiştirildi, bu nedenle güncellenmiş verileri dosyaya yazın:

with open("some_file.txt","w") as f:
    for line in newline:
        f.writelines(line)

Her iki durumda da çıktı şu olacaktır:

Dan                   Dan           
Warrior   ------>     Mage       
500                   500           
1                     1   
0                     0           

3

Metniniz yalnızca bir kişi içeriyorsa:

import re

# creation
with open('pers.txt','wb') as g:
    g.write('Dan \n Warrior \n 500 \r\n 1 \r 0 ')

with open('pers.txt','rb') as h:
    print 'exact content of pers.txt before treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt before treatment:\n',h.read()


# treatment
def roplo(file_name,what):
    patR = re.compile('^([^\r\n]+[\r\n]+)[^\r\n]+')
    with open(file_name,'rb+') as f:
        ch = f.read()
        f.seek(0)
        f.write(patR.sub('\\1'+what,ch))
roplo('pers.txt','Mage')


# after treatment
with open('pers.txt','rb') as h:
    print '\nexact content of pers.txt after treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt after treatment:\n',h.read()

Metniniz birkaç kişi içeriyorsa:

yeniden ithal

# creation
with open('pers.txt','wb') as g:
    g.write('Dan \n Warrior \n 500 \r\n 1 \r 0 \n Jim  \n  dragonfly\r300\r2\n10\r\nSomo\ncosmonaut\n490\r\n3\r65')

with open('pers.txt','rb') as h:
    print 'exact content of pers.txt before treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt before treatment:\n',h.read()


# treatment
def ripli(file_name,who,what):
    with open(file_name,'rb+') as f:
        ch = f.read()
        x,y = re.search('^\s*'+who+'\s*[\r\n]+([^\r\n]+)',ch,re.MULTILINE).span(1)
        f.seek(x)
        f.write(what+ch[y:])
ripli('pers.txt','Jim','Wizard')


# after treatment
with open('pers.txt','rb') as h:
    print 'exact content of pers.txt after treatment:\n',repr(h.read())
with open('pers.txt','rU') as h:
    print '\nrU-display of pers.txt after treatment:\n',h.read()

Bir bireyin "işi" metinde sabit uzunlukta olsaydı, metnin yalnızca "işe" karşılık gelen kısmını, istenen kişiye değiştirebilirsiniz: bu, göndereninkiyle aynı fikirdir.

Ama bana göre, bireylerin özelliklerini cPickle dosyasında kaydedilmiş bir sözlüğe koymak daha iyi olur:

from cPickle import dump, load

with open('cards','wb') as f:
    dump({'Dan':['Warrior',500,1,0],'Jim':['dragonfly',300,2,10],'Somo':['cosmonaut',490,3,65]},f)

with open('cards','rb') as g:
    id_cards = load(g)
print 'id_cards before change==',id_cards

id_cards['Jim'][0] = 'Wizard'

with open('cards','w') as h:
    dump(id_cards,h)

with open('cards') as e:
    id_cards = load(e)
print '\nid_cards after change==',id_cards

2

Bu akşam dosyalar üzerinde çalışma alıştırması yaptım ve tekrarlı / çoklu kullanım için daha fazla işlevsellik sağlamak için Jochen'in cevabını geliştirebileceğimi fark ettim. Maalesef cevabım büyük dosyalarla uğraşma sorununu ele almıyor ancak daha küçük dosyalarda hayatı kolaylaştırıyor.

with open('filetochange.txt', 'r+') as foo:
    data = foo.readlines()                  #reads file as list
    pos = int(input("Which position in list to edit? "))-1  #list position to edit
    data.insert(pos, "more foo"+"\n")           #inserts before item to edit
    x = data[pos+1]
    data.remove(x)                      #removes item to edit
    foo.seek(0)                     #seeks beginning of file
    for i in data:
        i.strip()                   #strips "\n" from list items
        foo.write(str(i))

0

Bunu yapmanın en kolay yolu budur.

fin = open("a.txt")
f = open("file.txt", "wt")
for line in fin:
    f.write( line.replace('foo', 'bar') )
fin.close()
f.close()

Umarım sizin için çalışacaktır.


-1
#read file lines and edit specific item

file=open("pythonmydemo.txt",'r')
a=file.readlines()
print(a[0][6:11])

a[0]=a[0][0:5]+' Ericsson\n'
print(a[0])

file=open("pythonmydemo.txt",'w')
file.writelines(a)
file.close()
print(a)

1
Stack Overflow'a hoş geldiniz! Lütfen çok eski ve önceden cevaplanmış bir soruyu yanıtladığınızı unutmayın. İşte Nasıl Cevaplanacağına dair bir rehber .
help-info.de

@ ajay-jaiswal Lütfen sorunuzu belirtin ve tekrarlanabilir minimum bir örnek ve aldığınız hata mesajlarını sağlayın. Kodu gönderdiniz, ancak asıl soruyu göndermediniz.
dmitryro

-2

file_nameAşağıdaki gibi bir dosyam olduğunu varsayalım :

this is python
it is file handling
this is editing of line

2. satırı "değişiklik yapıldı" ile değiştirmeliyiz:

f=open("file_name","r+")
a=f.readlines()
for line in f:
   if line.startswith("rai"):
      p=a.index(line)
#so now we have the position of the line which to be modified
a[p]="modification is done"
f.seek(0)
f.truncate() #ersing all data from the file
f.close()
#so now we have an empty file and we will write the modified content now in the file
o=open("file_name","w")
for i in a:
   o.write(i)
o.close()
#now the modification is done in the file
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.