Python - 删除文件中的最后一个字符

use*_*562 36 python text file

在浏览了整个互联网之后,我来到了这里.

假设我已经创建了一个文本文件: Hello World

好吧,我想d从这个文本文件中删除最后一个字符(在本例中).

所以现在文本文件应该如下所示: Hello Worl

但我不知道该怎么做.

我想要的或多或少都是我硬盘上文本文件的单一退格功能.

这需要在Linux上工作,就像我正在使用的那样.

Mar*_*ers 59

用于file.seek()从末尾寻找1个位置,然后用于file.truncate()删除文件的其余部分:

with open(filename, 'rb+') as filehandle:
    filehandle.seek(-1, os.SEEK_END)
    filehandle.truncate()
Run Code Online (Sandbox Code Playgroud)

  • @zvyn:您正在查看错误的文档.请参阅[`io.IOBase.seek()`](https://docs.python.org/3/library/io.html?highlight=newline#io.IOBase.seek).该文件以*二进制模式*打开,而不是文本模式.在文本模式中,偏移量取决于可以使用可变长度字节的文本的编码; 这就是为什么`TextIOBase.seek()`方法不支持向后搜索的原因.但在二进制模式下,我们用字节代替,而从末端开始的负偏移是完全合法的. (4认同)

qua*_*oft 8

接受Martijn的答案很简单,也很有效,但是不能解释具有以下内容的文本文件:

  • 包含非英语字符的UTF-8编码(这是Python 3中文本文件的默认编码)
  • 文件末尾一个换行符(这是Linux编辑器(如vimgedit)中的默认字符

如果文本文件包含非英语字符,那么到目前为止提供的答案均无效。

下面是一个示例,它解决了两个问题,也允许从文件末尾删除多个字符:

import os


def truncate_utf8_chars(filename, count, ignore_newlines=True):
    """
    Truncates last `count` characters of a text file encoded in UTF-8.
    :param filename: The path to the text file to read
    :param count: Number of UTF-8 characters to remove from the end of the file
    :param ignore_newlines: Set to true, if the newline character at the end of the file should be ignored
    """
    with open(filename, 'rb+') as f:
        last_char = None

        size = os.fstat(f.fileno()).st_size

        offset = 1
        chars = 0
        while offset <= size:
            f.seek(-offset, os.SEEK_END)
            b = ord(f.read(1))

            if ignore_newlines:
                if b == 0x0D or b == 0x0A:
                    offset += 1
                    continue

            if b & 0b10000000 == 0 or b & 0b11000000 == 0b11000000:
                # This is the first byte of a UTF8 character
                chars += 1
                if chars == count:
                    # When `count` number of characters have been found, move current position back
                    # with one byte (to include the byte just checked) and truncate the file
                    f.seek(-1, os.SEEK_CUR)
                    f.truncate()
                    return
            offset += 1
Run Code Online (Sandbox Code Playgroud)

怎么运行的:

  • 以二进制模式仅读取UTF-8编码的文本文件的最后几个字节
  • 向后迭代字节,查找UTF-8字符的开头
  • 找到一个字符(与换行符不同)后,将其作为文本文件中的最后一个字符返回

样本文本文件- bg.txt

??????? ????
Run Code Online (Sandbox Code Playgroud)

如何使用:

filename = 'bg.txt'
print('Before truncate:', open(filename).read())
truncate_utf8_chars(filename, 1)
print('After truncate:', open(filename).read())
Run Code Online (Sandbox Code Playgroud)

输出:

Before truncate: ??????? ????
After truncate: ??????? ???
Run Code Online (Sandbox Code Playgroud)

这适用于UTF-8和ASCII编码文件。


daw*_*awg 6

with open(urfile, 'rb+') as f:
    f.seek(0,2)                 # end of file
    size=f.tell()               # the size...
    f.truncate(size-1)          # truncate at that size - how ever many characters
Run Code Online (Sandbox Code Playgroud)

一定要在 Windows 上使用二进制模式,因为 Unix 文件行结尾 many 返回非法或不正确的字符数。


met*_*urk 5

如果你没有以二进制模式读取文件,你只有'w'权限,我可以建议如下.

f.seek(f.tell() - 1, os.SEEK_SET)
f.write('')
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,f.seek()只接受f.tell()您没有"b"访问权限的b/c.然后你可以将光标设置为最后一个元素的开头.然后,您可以用空字符串删除最后一个元素.