如何使用Python编辑文本文件?

3
text = open('samiam.txt', 'r+')
keyword = " i "
keyword2 = "-i-"
replacement = " I "
replacement2 = "-I-"

for line in text:    
    if keyword in line:
        text.write(line.replace(keyword, replacement))
        print line
    elif keyword2 in line:
        text.write(line.replace(keyword2, replacement2))
        print line
    else:
        print line
text.close()

我不确定为什么文本没有被写入文件。请帮忙?

1
你能展示一下你的文件样本吗? - WannaBeCoder
我是山姆 山姆,我就是 那个山姆! 那个山姆! 我不喜欢那个山姆! 你喜欢 绿色的鸡蛋和火腿吗? 我不喜欢,山姆。 我不喜欢 绿色的鸡蛋和火腿。 - Andrea
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - glglgl
@triplee 你说得对!你认为我需要一副新眼镜吗?对于我的误解,我向OP道歉。 - gboffi
1
@Andrea 永远不要将你的代码打出来,而应该复制粘贴它... - gboffi
显示剩余6条评论
4个回答

2
在你的代码中,只需替换这一行。
for line in text:

使用

for line in text.readlines():

请注意,这里假设您正在尝试将输出添加到文件末尾。一旦您读取了整个文件,文件指针就位于文件末尾(即使您以r+模式打开文件)。因此,进行写操作实际上会在当前内容之后向文件末尾写入。
您可以通过在不同的行中嵌入text.tell()来检查文件指针。
这是另一种方法:
with open("file","r") as file: 
    text=file.readlines() 
i=0 
while i < len(text): 
    if keyword in text[i]: 
        text[i]=text[i].replace(keywork,replacement) 
with open("file","w") as file: 
    file.writelines(text)

我不是给你点踩的人,但我确实检查了这个答案,似乎没有改变任何东西。 - Andrea
实际上它确实改变了事情,但是对它所做的描述很差,而且这可能不是你想要的。他试图表达的意思,在咒骂和格式不佳之间,是当你正在从文件中间读取时,你不能写到文件的末尾。这个更改修复了这个问题,但最终会将新输出追加到文件的末尾,而不是重写整个文件。 - tripleee
我已经提到过,在阅读代码后,我假设只有这样。如果你真的想重写,为什么不打开文件,将其保存在列表中,在修改列表后再写回文件呢?代码的问题在于,在读取文件后,文件指针移动到末尾,因此除非移动文件指针,否则无法重写现有行。 - Prakash Kuma
@tripleee,就糟糕的格式而言,您可以查看我从昨天开始就一直在努力尽可能准确。我真的不知道什么是适当的格式规则,还在学习中。 Andrea,我知道你没有投反对票,我也没有指向你,因为你像我一样没有足够的积分来投反对票。 - Prakash Kuma
是的,r+既可以读取文件,也可以写入文件。但问题可能出在文件指针上。如果您还没有看过它们,请查看以下链接。https://dev59.com/qmYq5IYBdhLWcg3wtCoo.http://bugs.python.org/issue3207 - Prakash Kuma
我通常做的是这样的。with open("file","r") as file: text=file.readlines() i=0 while i < len(text): if keyword in text[i]: text[i]=text[i].replace(keywork,replacement)with open("file","w") as file: file.writelines(text) - Prakash Kuma

1

最好使用两个描述符——一个用于读取,另一个用于写入,以提高可读性和单次写操作。

text_read = open('samiam.py', 'r').read()
words_replacer_dict = {" i " : " I ", "-i-" : "-I-"}
replaced_text = ""

for line in text_read.split("\n"):
    for word, new_word in words_replacer_dict.items():
        replaced_text += line.replace(word, new_word)

text_read.close()
text_write = open('samiam.py', 'w')
text_write.write(replaced_text)
text_write.close()

你甚至可以按计数器写入内容,如果你关心内存的话。只需在生成器表达式中以读模式打开文件并保留引用计数即可满足写操作。 注意:阅读此处(非官方链接)以更好地了解字典方法。
然而,如果你更喜欢使用读写操作,请始终使用seek操作找到要替换的行,并在完成文件写入后使用flush。但是,你无法通过seek和flush方法替换文件中已经存在的行。你只能向文件中添加一些内容。(例如)
text = open('samiam.py', 'r+')
count = 1
new_text = ""
for line in text:
    new_text += "%d:%s\n" % (count, line)
    count += 1
text.seek(0)
text.truncate()
text.write(new_text)
text.seek(0)
for line in text:
    print line
text.close()

为了更好地理解为什么不能像你希望的那样读写文件,请查看这里


new_word是字典中的值(例如“我”,“-I-”)。 - thiruvenkadam
为了更好地阅读原因,请点击链接。链接中说:“不幸的是,没有办法在不重写文件的情况下插入到文件中间。”但是,我可以接受重新编写它...我想。 - Andrea
字典末尾的'items'是什么意思?我查了但还是不理解... - Andrea
项将以两个值的元组列表形式给出字典。例如,{'a':1, 'b':2} => [('a',1), ('b', 2)]。 - thiruvenkadam

1
使用 fileinput 模块。(另请参见MOTW 网站。)
import fileinput
keyword1 = " i "
keyword2 = "-i-"
replacement1 = " I "
replacement2 = "-I-"
for line in fileinput.input('your.file', inplace=True):
    line = line.rstrip()
    if keyword1 in line:
        line = line.replace(keyword1, replacement1)
    elif keyword2 in line:
        line = line.replace(keyword2, replacement2)
    print line

当您使用inplace选项时,fileinput模块会重命名输入文件并将stdout重定向到具有原始文件名的新文件。
如果要保留每行右侧的空格,请勿rstrip,并使用print line,(请注意最后的逗号)输出处理后的行。

什么是 "line.rstrip()"?我理解去除空格的概念...但为什么前面要加上 'r'? - Andrea
有不同的函数可以从两侧、从左侧或从右侧剥离字符串。rstrip只从右侧剥离,即从字符串末尾开始。 - tripleee
它的剥离程度是多少? 假设这行是“我不喜欢他们,山姆-爱姆。” ...那会有什么变化? - Andrea
'r'代表“右”。在这里,我们使用print将一个换行符添加到它打印的内容中,因此如果输出文件中的line包含一个换行符,则所有文本行都将由一个空行分隔。为了避免这种行为,我们剥离右侧的所有空格,假设左侧的空格是有意义的(即缩进是有意义的),而右侧的空格可以牺牲以获得适当的输出格式。如果您想保留所有空格,请不要使用rstrip并使用print line,(带有最后的逗号),以便不会附加进一步的换行符。 - gboffi
我必须说,显然你不知道从文件中读取的每一行都以换行符终止... 你正在处理的那一行不是 "i do not like them, sam-i-am." 而是 "i do not like them, sam-i-am.\n",你看到区别了吗? - gboffi

0

这是因为您正在尝试同时读取和写入。请尝试以下操作:

# Read operation
lines = []
for line in text.readlines():
    if keyword in line:
        lines.append(line.replace(keyword, replacement))
        print line
    elif keyword2 in line:
        lines.append(line.replace(keyword2, replacement2))
        print line
    else:
        lines.append(line)
        print line
text.close()

# Write operation
text = open('dummy.py', 'w+')
text.writelines(lines)
text.close()

额外奖励:

with open('data.txt') as f:
     data = f.read()

更符合Python风格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接