在Python中编辑文本文件中的特定行


86

假设我有一个包含以下内容的文本文件:

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]是不正确的。但是你明白我的意思吧?我正在尝试通过用法师替换战士来编辑第2行。但是我什至可以那样做吗?


1
我觉得这个职位涵盖了你在找什么:stackoverflow.com/questions/1998233/...
凯尔狂野

1
如果您必须做很多这样的事情,则可能需要考虑将此文件从文本转换为bdb或其他类似bdb的东西。
尼克·巴斯汀

Answers:


123

您想做这样的事情:

# 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”。


2
嗨,Jochen,语句“ with open(filename,mode)”在程序退出后也会隐式关闭文件名,对吗?
Radu 2014年

@Gabriel Thx,值得注意的是,尽管我仍然不使用with ...作为文件语句。是否使用Pythonic,我不喜欢:)
Radu 2015年

@Radu这是习惯的问题。我还曾经通过手动关闭打开的文件,close.但是现在我看到使用with块更干净了。
加百利2015年

5
假设正确吗?这是小文件的首选解决方案吗?否则,我们可能需要大量内存才能存储数据。此外,即使进行1次编辑,我们也需要重新编写整个内容。
Arindam Roychowdhury

11
不好..如果您有20 Gb文件怎么办?
Brans Ds

21

您可以使用fileinput进行就地编辑

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

然后:

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

9
这会将整个文件的内容加载到内存中,如果文件很大,那可能不是一件好事。
Steve Ng 2014年

@SteveNg您是否对发现的问题有解决方案?这个答案和被接受的答案都依赖于将整个文件加载到内存中
Blupon

13

您可以通过两种方式来做到这一点,选择适合您需求的方式:

方法I。)使用行号替换。enumerate()在这种情况下,您可以使用内置函数:

首先,在读取模式下,将所有数据保存在一个变量中

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

其次,写入文件(枚举生效)

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.  

“战士”已由“法师”代替,因此将更新后的数据写入文件:

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

这是两种情况下的输出结果

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

3

如果您的文本仅包含一个人:

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

2

我今晚一直在练习处理文件,并意识到我可以根据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))

0

这是最简单的方法。

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

希望它对您有用。


-1

#读取文件行并编辑特定项目

file = open(“ pythonmydemo.txt”,'r')

a = file.readlines()

打印(a [0] [6:11])

a [0] = a [0] [0:5] +'爱立信\ n'

打印(a [0])

file = open(“ pythonmydemo.txt”,'w')

file.writelines(a)

file.close()

打印(a)


1
欢迎使用Stack Overflow!请注意,您回答的是一个非常古老且已经回答的问题。这是有关如何回答的指南。
help-info.de

-2

假设我有一个名为file_name以下文件:

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

我们必须将第2行替换为“修改完成”:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.