我有一个包含ID和信息的文件,如下所示:
1oMZgkoaz3o 2011-12-29T01:23:00.000Z 9 503 ApolloIsMyCoPilot
nUW1TomCSQg 2011-12-29T01:23:15.000Z 9 348 grea7stuff
tJuLnRrAcs0 2011-12-29T01:26:20.000Z 9 123 AdelGaming
tyi5g0mnPIs 2011-12-29T01:28:07.000Z 9 703 PreferredGaming
我想在某些行上添加一个标志,所以如果我有一个字典
flags = {'1oMZgkoaz3o': flag1, 'tJuLnRrAcs0': flag2}
我想要的结果是
1oMZgkoaz3o 2011-12-29T01:23:00.000Z 9 503 ApolloIsMyCoPilot flag1
nUW1TomCSQg 2011-12-29T01:23:15.000Z 9 348 grea7stuff
tJuLnRrAcs0 2011-12-29T01:26:20.000Z 9 123 AdelGaming flag2
tyi5g0mnPIs 2011-12-29T01:28:07.000Z 9 703 PreferredGaming
所以我制作了这段代码
l = True
while l is True:
a = f.readline()
try a.split(' ')[0] in flags.iterkeys():
f.seek(-1,1)
f.write(' '+str(flags[a.split(' ')[0]])+'\n')
del flags[a.split(' ')[0]]
except IndexError:
l = False
所以,我的Python代码可能很差,但问题是这个代码我正在替换文本,所以文件都搞砸了。如何在不更换的情况下书写?如果您对代码有更好的想法,欢迎您...
答案 0 :(得分:9)
您无法写入文件并“插入”。最好的方法是读取您的文件并写出内容并修改新文件,然后根据需要重命名。
答案 1 :(得分:6)
我在这里看到两个问题:
这不太好用。从一个文件读取并写入另一个文件会更好(这样,如果程序出现问题,也不会丢失数据)。例如:
input_file = open('infile.txt', 'r')
output_file = open('outfile.txt', 'w')
for line in input_file:
line += "transformed"
output_file.write(line)
您的代码段中有一个语法错误,即行
try a.split(' ')[0] in flags.iterkeys():
无效(Python应该抱怨!)。
其他一些注意事项:
in flags.iterkeys()
在语义上等同于in flags
while l
代替while l is True
。更好的是,如果发生错误,您可以完全删除标志变量l
并使用break
跳出循环。input_file = open('infile.txt', 'r')
output_file = open('outfile.txt', 'w')
flags = { ... }
for line in input_file:
parts = line.strip().split()
if parts[0] in flags:
line = line + ' ' + flags[parts[0]]
output_file.write(line + "\n")
如果您知道如何使用shell,那么只需使用STDIN / STDOUT进行数据输入和输出,就可以让您的生活更轻松。您可以自己保存文件处理,并让用户更灵活地使用您的脚本。
答案 2 :(得分:2)
我想使用stdin/stdout
重定向:
#!/usr/bin/env python3
import sys
flags = {'1oMZgkoaz3o': 'flag1', 'tJuLnRrAcs0': 'flag2'}
for line in sys.stdin:
line = line.rstrip()
k = line.split()[0]
if k in flags:
print(line, flags[k])
else:
print(line)
$ python3 script.py <input.txt >output.txt
$ cat output.txt
1oMZgkoaz3o 2011-12-29T01:23:00.000Z 9 503 ApolloIsMyCoPilot flag1
nUW1TomCSQg 2011-12-29T01:23:15.000Z 9 348 grea7stuff
tJuLnRrAcs0 2011-12-29T01:26:20.000Z 9 123 AdelGaming flag2
tyi5g0mnPIs 2011-12-29T01:28:07.000Z 9 703 PreferredGaming
答案 3 :(得分:2)
使用fileinput
模块可以就地修改文件:
from fileinput import FileInput
f = FileInput(the_filename, inplace=True)
for line in f:
line = modify_line() # do whatever modifications you need to do
print line # this writes the line to the file
f.close()
答案 4 :(得分:0)
首先,让我们稍微清理一下脚本:
for line in f.readlines():
line = line.strip()
parts = line.split()
if parts[0] in flags:
f.write(line + flags[parts[0]] + "\n");
else:
f.write(line + "\n");
自从我上次阅读和写入同一个文件以来,已经有一段时间了,所以我可能会有点休息。
答案 5 :(得分:0)
问题的根源在于您尝试读取和写入同一文件对象。您需要创建一个新文件。
但是,还有一些其他事项应该考虑先清理......
首先,您可以通过直接迭代文件对象而不是使用while循环来简化操作。 E.g:
flags = {'1oMZgkoaz3o': 'flag1', 'tJuLnRrAcs0': 'flag2'}
# The "with" statement automatically closes the file when we're done with it
with open('test.txt', 'r') as infile:
# If we just iterate over the open file, we're iterating over the lines in it
for line in infile:
line = line.strip().split()
key = line[0]
# I'm using "flags.get" with a default arugment here. If "key" isn't in
# "flags", then an empty string will be returned.
line.append(flags.get(key, ''))
print ' '.join(line)
在这个例子中,我们只是打印我们想要的输出。如果文件很小,那么我们可以轻松地做这样的事情
flags = {'1oMZgkoaz3o': 'flag1', 'tJuLnRrAcs0': 'flag2'}
with open('test.txt', 'r') as infile:
# Load the entire contents of the file into memory...
lines = infile.readlines()
with open('test.txt', 'w') as outfile:
for line in lines:
print line
line = line.strip().split()
line.append(flags.get(line[0], ''))
outfile.write(' '.join(line) + '\n')
但是,如果它是一个大文件,我们可能不希望将整个副本读入内存。
在这种情况下,我们希望迭代原始文件并写入不同的文件。然后我们需要将新文件重命名为原始文件的名称。
如果我们要非常小心,我们会做以下事情:
import os
flags = {'1oMZgkoaz3o': 'flag1', 'tJuLnRrAcs0': 'flag2'}
infile = open('test.txt', 'r')
outfile = open('test2.txt', 'w')
try:
# Try to do this...
for line in infile:
line = line.strip().split()
line.append(flags.get(line[0], ''))
outfile.write(' '.join(line) + '\n')
finally:
# Do this no matter what...
infile.close()
outfile.close()
# If nothing goes wrong, do this...
os.remove('test.txt')
os.rename('test2.txt', 'test.txt')
try:... finally:...
部分基本上是手动执行with
语句对文件对象的操作。在这种特殊情况下,它可以说比使用语句嵌套两个更清晰,但是我主要使用它来显示执行此操作的备用(较旧)语法。理想情况下,您可能会编写与此类似的代码:
import os
def main():
flags = {'1oMZgkoaz3o': 'flag1', 'tJuLnRrAcs0': 'flag2'}
with open('test.txt', 'r') as infile:
with open('test2.txt', 'w') as outfile:
append_flags(infile, outfile, flags)
os.remove('test.txt')
os.rename('test2.txt', 'test.txt')
def append_flags(infile, outfile, flags):
for line in infile:
line = line.strip().split()
line.append(flags.get(line[0], ''))
outfile.write(' '.join(line) + '\n')
main()
然而,随着我们的进一步发展,我们显然变得越来越复杂。
在您的情况下,第二个示例(将整个文件读入内存然后写入原始文件)可能就是您想要的。