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

发布于 2024-10-07 18:52:47 字数 281 浏览 7 评论 0原文

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

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

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

f.write(temp)
f.close()

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

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:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

最丧也最甜 2024-10-14 18:52:47

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

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

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

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

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.

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.

离去的眼神 2024-10-14 18:52:47

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

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

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

with open('filename', 'r') as original:
    data = original.read()
with open('filename', 'w') as modified:
    modified.write("new first line\n" + data)
寄居者 2024-10-14 18:52:47

其他方法:

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

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

干杯

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

唔猫 2024-10-14 18:52:47
with open("file", "r+") as f: s = f.read(); f.seek(0); f.write("prepend\n" + s)
with open("file", "r+") as f: s = f.read(); f.seek(0); f.write("prepend\n" + s)
灰色世界里的红玫瑰 2024-10-14 18:52:47

您可以这样保存一个写入调用:

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

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

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.

深居我梦 2024-10-14 18:52:47

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

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

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.

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()
虫児飞 2024-10-14 18:52:47

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

This does the job without reading the whole file into memory, though it may not work on 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)
川水往事 2024-10-14 18:52:47

一种可能性如下:

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

One possibility is the following:

import os
open('tempfile', 'w').write('#testfirstline\n' + open('filename', 'r').read())
os.rename('tempfile', 'filename')
陈独秀 2024-10-14 18:52:47

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

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

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

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.

彻夜缠绵 2024-10-14 18:52:47

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

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

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 open and keep exchanging file<->buffer contents?

This seems much more efficient (for big files especially) than reading the whole content in memory, modifying it in memory and 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.

阳光下的泡沫是彩色的 2024-10-14 18:52:47

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

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="")

As I suggested in this answer, you can do it using the following:

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="")
ゝ偶尔ゞ 2024-10-14 18:52:47

如果你像这样重写它:

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

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

If you rewrite it like this:

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

It's rather short and simple.
For 'r+' the file needs to exist already.

桃扇骨 2024-10-14 18:52:47

这对我有用

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

this worked for me

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()
一个人练习一个人 2024-10-14 18:52:47

使用操作系统库怎么样?

在这种特殊情况下,使用 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 字符串。该过程不会重写整个文件结构,并且可以处理大文件。

What about using OS library.

In this particular case with OS Linux and using the sed function

import os

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

This will create a new line into the specified file_name location and insert the header string. This process does not rewrite the whole file structure and can process big files.

丑丑阿 2024-10-14 18:52:47

使用 pathlib.Path read_text()write_text() 添加到简明地归档:

from pathlib import Path

file = Path("filename")
original = file.read_text()
file.write_text(f"new first line\n{original}")

Use pathlib.Path read_text() and write_text() to prepend to a file concisely:

from pathlib import Path

file = Path("filename")
original = file.read_text()
file.write_text(f"new first line\n{original}")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文