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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4454298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 15:48:58  来源:igfitidea点击:

Prepend a line to an existing file in Python

pythonprepend

提问by Nick

I need to add a single line to the first line of a text file and it looks like the only options available to me are more lines of code than I would expect from python. Something like this:

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

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

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

f.write(temp)
f.close()

Is there no easier way? Additionally, I see this two-handle example more often than opening a single handle for reading and writing ('r+') - why is that?

没有更简单的方法吗?此外,我看到这个双句柄示例比打开单个句柄进行读写 ('r+') 的频率更高 - 为什么会这样?

采纳答案by Nicholas Knight

Python makes a lot of things easy and contains libraries and wrappers for a lot of common operations, but the goal is not to hide fundamental truths.

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

The fundamental truth you are encountering here is that you generally can't prepend data to an existing flat structure without rewriting the entire structure. This is true regardless of language.

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

There are ways to save a filehandle or make your code less readable, many of which are provided in other answers, but none change the fundamental operation: You must read in the existing file, then write out the data you want to prepend, followed by the existing data you read in.

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

By all means save yourself the filehandle, but don't go looking to pack this operation into as few lines of code as possible. In fact, never go looking for the fewest lines of code -- that's obfuscation, not programming.

一定要保存文件句柄,但不要试图将这个操作打包成尽可能少的代码行。事实上,永远不要寻找最少的代码行——那是混淆,而不是编程。

回答by infrared

You can save one write call with this:

您可以通过以下方式保存一次写入调用:

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

When using 'r+', you would have to rewind the file after reading and before writing.

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

回答by JooMing

One possibility is the following:

一种可能性如下:

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

回答by Morlock

Other approach:

其他方法:

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

or a one liner:

或单班轮:

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

Thanks for the opportunity to think about this problem :)

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

Cheers

干杯

回答by barti_ddu

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

回答by Karl Knechtel

I would stick with separate reads and writes, but we certainly can express each more concisely:

我会坚持单独的读取和写入,但我们当然可以更简洁地表达:

Python2:

蟒蛇2:

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

Python3:

蟒蛇3:

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

Note: file() function is not available in python3.

注意:file() 函数在 python3 中不可用。

回答by eug

This does the job without reading the whole file into memory, though it may not work on Windows

这可以在不将整个文件读入内存的情况下完成工作,尽管它可能无法在 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)

回答by Love and peace - Joe Codeswell

Here's a 3 liner that I think is clear and flexible. It uses the list.insert function, so if you truly want to prepend to the file use l.insert(0, 'insert_str'). When I actually did this for a Python Module I am developing, I used l.insert(1, 'insert_str') because I wanted to skip the '# -- coding: utf-8 --' string at line 0. Here is the code.

这是我认为清晰且灵活的 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()

回答by Pithikos

If you wish to prepend in the file after a specific text then you can use the function below.

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

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

So first you open the file, read it and save it all into one string. Then we try to find the character number in the string where the injection will happen. Then with a single write and some smart indexing of the string we can rewrite the whole file including the injected text now.

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

回答by Zuzu Corneliu

Am I not seeing something or couldn't we just use a buffer large-enough to read-in the input file in parts(instead of the whole content) and with this buffer traverse the file while it is openand keep exchanging file<->buffer contents?

我是不是没有看到某些东西,或者我们不能只使用一个足够大的缓冲区来读取部分(而不是整个内容)的输入文件并在文件打开时使用该缓冲区遍历文件并继续交换文件<- > 缓冲内容?

This seems much more efficient (for big files especially) than reading the wholecontent in memory, modifying it in memoryand writing it back to the same file or (even worse) a different one. Sorry that now I don't have time to implement a sample snippet, I'll get back to this later, but maybe you get the idea.

这似乎更有效(对于大文件尤其是)比读取全部内容在内存中,修改它在内存和写回同一个文件或者(更糟糕的)不同的一个。抱歉,现在我没有时间实现示例代码段,稍后我会回到这个问题,但也许你明白了。