web-dev-qa-db-ja.com

Pythonのテキストファイルの特定の行の編集

次を含むテキストファイルがあるとします。

Dan
Warrior
500
1
0

そのテキストファイルの特定の行を編集する方法はありますか?今私はこれを持っています:

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

はい、myfile.writelines('Mage')[1]が正しくないことを知っています。しかし、あなたは私の意見を理解しますよね? WarriorをMageに置き換えて2行目を編集しようとしています。しかし、私もそれをすることができますか?

61
test

あなたはこのようなことをしたい:

# 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 )

これは、ファイル内で「行2の変更」のようなことを直接行うことができないためです。ファイルの一部のみを上書きできます(削除はできません)。つまり、新しいコンテンツは古いコンテンツのみをカバーします。したがって、2行目に「Mage」と記述した場合、結果の行は「Mageior」になります。

85
Jochen Ritzel

fileinputを使用してインプレース編集を行うことができます

import fileinput
for  line in fileinput.FileInput("myfile", inplace=1):
    if line .....:
         print line
18
ghostdog74
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()

その後:

replace_line('stats.txt', 0, 'Mage')
16
Peter C

テキストに個人が1人しか含まれていない場合:

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()

テキストに複数の個人が含まれる場合:

再インポート

# 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()

テキストの個人の「ジョブ」が一定の長さである場合、目的の個人の「ジョブ」に対応するテキストの部分のみを変更できます。これは送信者のアイデアと同じです。

しかし、私によれば、個人の特性をcPickleでファイルに記録された辞書に入れる方が良いでしょう。

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
3
eyquem

次の2つの方法で行うことができ、要件に合ったものを選択します。

方法I)行番号を使用して置き換える。この場合、組み込み関数enumerate()を使用できます。

まず、読み取りモードで変数内のすべてのデータを取得します

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

次に、ファイルに書き込みます(enumerateが実行されます)

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)

方法II。)置換したいキーワードの使用:

読み取りモードでファイルを開き、内容をリストにコピーします

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.  

「Warrior」は「Mage」に置き換えられているため、更新されたデータをファイルに書き込みます。

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

これは、両方のケースでoutputになります。

Dan                   Dan           
Warrior   ------>     Mage       
500                   500           
1                     1   
0                     0           
2
Aseem Yadav

私は今晩、ファイルの作業を練習してきましたが、Jochenの答えに基づいて、繰り返し/複数回使用するための優れた機能を提供できることに気付きました。残念なことに、私の答えは大きなファイルを扱う問題に対処していませんが、小さなファイルでの生活を楽にします。

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))
2
theYnot