使用python在文件中添加文本(不替换它)

时间:2012-01-12 15:51:34

标签: python

我有一个包含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代码可能很差,但问题是这个代码我正在替换文本,所以文件都搞砸了。如何在不更换的情况下书写?如果您对代码有更好的想法,欢迎您...

6 个答案:

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

然而,随着我们的进一步发展,我们显然变得越来越复杂。

在您的情况下,第二个示例(将整个文件读入内存然后写入原始文件)可能就是您想要的。