在 Python 中的现有文件中添加一行

问题描述 投票:0回答:14

我需要在文本文件的第一行添加一行,看起来我唯一可用的选项是比我期望的 python 代码行数更多。像这样的东西:

f = open('filename','r')
temp = f.read()
f.close()

f = open('filename', 'w')
f.write("#testfirstline")

f.write(temp)
f.close()

有没有更简单的方法?此外,我更经常看到这个两个句柄的示例,而不是打开单个句柄进行读写(“r+”) - 这是为什么?

python prepend
14个回答
114
投票

Python 让很多事情变得简单,并包含许多常见操作的库和包装器,但目标不是隐藏基本事实。

您在这里遇到的基本事实是,您通常无法在不重写整个结构的情况下将数据添加到现有的平面结构中。无论语言如何,这都是事实。

有很多方法可以保存文件句柄或使代码可读性较差,其中许多方法在其他答案中提供,但没有改变基本操作:您必须读入现有文件,然后写出要添加的数据,然后通过您读入的现有数据。

无论如何都要保存文件句柄,但不要试图将此操作打包到尽可能少的代码行中。事实上,永远不要去寻找最少的代码行——那是混淆,而不是编程。


98
投票

我会坚持分开读取和写入,但我们当然可以更简洁地表达每一个:

with open('filename', 'r') as original:
    data = original.read()
with open('filename', 'w') as modified:
    modified.write("new first line\n" + data)

27
投票

其他方法:

with open("infile") as f1:
    with open("outfile", "w") as f2:
        f2.write("#test firstline")
        for line in f1:
            f2.write(line)

或单衬:

open("outfile", "w").write("#test firstline\n" + open("infile").read())

感谢您有机会思考这个问题:)

干杯


13
投票
with open("file", "r+") as f: s = f.read(); f.seek(0); f.write("prepend\n" + s)

3
投票

您可以使用以下命令保存一个写调用:

f.write('#testfirstline\n' + temp)

使用“r+”时,您必须在读取之后和写入之前倒带文件。


3
投票

这是一个 3 衬垫,我认为它清晰且灵活。它使用 list.insert 函数,因此如果您确实想在文件前面添加,请使用 l.insert(0, 'insert_str')。当我实际为正在开发的 Python 模块执行此操作时,我使用了 l.insert(1, 'insert_str') 因为我想跳过第 0 行的 '# --coding: utf-8 --' 字符串。这是代码。

f = open(file_path, 'r'); s = f.read(); f.close()
l = s.splitlines(); l.insert(0, 'insert_str'); s = '\n'.join(l)
f = open(file_path, 'w'); f.write(s); f.close()

2
投票

这无需将整个文件读入内存即可完成工作,尽管它可能无法在 Windows 上运行

def prepend_line(path, line):
    with open(path, 'r') as old:
        os.unlink(path)
        with open(path, 'w') as new:
            new.write(str(line) + "\n")
            shutil.copyfileobj(old, new)

1
投票

一种可能性如下:

import os
open('tempfile', 'w').write('#testfirstline\n' + open('filename', 'r').read())
os.rename('tempfile', 'filename')

0
投票

如果您希望在文件中添加特定文本之后,则可以使用下面的功能。

def prepend_text(file, text, after=None):
    ''' Prepend file with given raw text '''
    f_read = open(file, 'r')
    buff = f_read.read()
    f_read.close()
    f_write = open(file, 'w')
    inject_pos = 0
    if after:
        pattern = after
        inject_pos = buff.find(pattern)+len(pattern)
    f_write.write(buff[:inject_pos] + text + buff[inject_pos:])
    f_write.close()

首先打开文件,读取它并将其全部保存到一个字符串中。 然后我们尝试在字符串中查找将发生注入的字符数。然后,通过一次写入和字符串的一些智能索引,我们现在可以重写整个文件,包括注入的文本。


0
投票

我没有看到什么吗,或者我们不能使用足够大的缓冲区来读入输入文件部分(而不是整个内容),并使用此缓冲区遍历文件当它打开时并且继续交换文件<->缓冲区内容?

这似乎比读取整个内容在内存中、修改它在内存中并将其写回同一个文件或(更糟糕)不同的文件要高效得多(尤其是对于大文件)。抱歉,现在我没有时间实现示例片段,我稍后会再讨论这个问题,但也许您已经明白了。


0
投票

正如我在this答案中所建议的,您可以使用以下方法来完成:

def prepend_text(filename: Union[str, Path], text: str):
    with fileinput.input(filename, inplace=True) as file:
        for line in file:
            if file.isfirstline():
                print(text)
            print(line, end="")

0
投票

如果你这样重写:

with open('filename') as f:
    read_data = f.read()
with open('filename', 'w') as f:
    f.write("#testfirstline\n" + read_data)

它相当简短。 对于“r+”,文件需要已经存在。


0
投票

这对我有用

def prepend(str, file):
    with open(file, "r") as fr:
        read = fr.read()
        with open(file, "w") as fw:
            fw.write(str + read)
            fw.close()

0
投票

使用操作系统库怎么样?

在这种特殊情况下,使用 Linux 操作系统并使用 sed 函数

import os

header = 'Your first line'
cmd_header = (r"sed -i '1s/^/" + f"{header}" + r"\n/'" + f" {file_name}")
os.cmd(cmd_header)

这将在指定的

file_name
位置创建一个新行并插入
header
字符串。这个过程不会重写整个文件结构,可以处理大文件。

© www.soinside.com 2019 - 2024. All rights reserved.