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

时间:2013-09-17 18:34:15

标签: python file text

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

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

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

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

但我不知道该怎么做。

我想要的只是或多或少,是我硬盘上文本文件的单一退格函数。

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

8 个答案:

答案 0 :(得分:57)

使用file.seek()从最后搜索1个位置,然后使用file.truncate()删除文件的其余部分:

with open(filename, 'rb+') as filehandle:
    filehandle.seek(-1, os.SEEK_END)
    filehandle.truncate()

答案 1 :(得分:5)

如果您不是以二进制模式(只有“ w”权限)读取文件,则可以提出以下建议。

f.seek(f.tell() - 1, os.SEEK_SET)
f.write('')

在上面的代码中,f.seek()将仅接受f.tell() b / c,而您没有'b'访问权限。那么您可以将光标设置到最后一个元素的开头。然后,您可以通过一个空字符串删除最后一个元素。

答案 2 :(得分:4)

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

确保在Windows上使用二进制模式,因为Unix文件行结尾很多会返回illegal or incorrect字符数。

答案 3 :(得分:4)

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

工作原理:

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

示例文本文件 - bg.txt

Здравей свят

使用方法:

filename = 'bg.txt'
print('Before truncate:', open(filename).read())
truncate_utf8_chars(filename, 1)
print('After truncate:', open(filename).read())

输出:

Before truncate: Здравей свят
After truncate: Здравей свя

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

答案 4 :(得分:2)

with open('file.txt', 'w') as f:
    f.seek(0, 2)              # seek to end of file; f.seek(0, os.SEEK_END) is legal
    f.seek(f.tell() - 2, 0)  # seek to the second last char of file; f.seek(f.tell()-2, os.SEEK_SET) is legal
    f.truncate()

以文件的最后一个字符为准,可以是换行符(\ n)或其他任何字符。

答案 5 :(得分:0)

这是一种肮脏的方式(擦除和重新创建)...... 我不建议使用它,但是,这样做可能就是这样..

elements[0]

答案 6 :(得分:0)

在Linux系统上(或Windows下的Cygwin)。您可以使用标准的truncate命令。您可以使用此命令来减小或增大文件的大小。

为了将文件减少1G,命令为truncate -s 1G filename。在下面的示例中,我将名为update.iso的文件减少了1G。

请注意,此操作不到五秒钟。

chris@SR-ENG-P18 /cygdrive/c/Projects
$ stat update.iso
  File: update.iso
  Size: 30802968576     Blocks: 30081024   IO Block: 65536  regular file
Device: ee6ddbceh/4000177102d   Inode: 19421773395035112  Links: 1
Access: (0664/-rw-rw-r--)  Uid: (1052727/   chris)   Gid: (1049089/Domain Users)
Access: 2020-06-12 07:39:00.572940600 -0400
Modify: 2020-06-12 07:39:00.572940600 -0400
Change: 2020-06-12 07:39:00.572940600 -0400
 Birth: 2020-06-11 13:31:21.170568000 -0400

chris@SR-ENG-P18 /cygdrive/c/Projects
$ truncate -s -1G update.iso

chris@SR-ENG-P18 /cygdrive/c/Projects
$ stat update.iso
  File: update.iso
  Size: 29729226752     Blocks: 29032448   IO Block: 65536  regular file
Device: ee6ddbceh/4000177102d   Inode: 19421773395035112  Links: 1
Access: (0664/-rw-rw-r--)  Uid: (1052727/   chris)   Gid: (1049089/Domain Users)
Access: 2020-06-12 07:42:38.335782800 -0400
Modify: 2020-06-12 07:42:38.335782800 -0400
Change: 2020-06-12 07:42:38.335782800 -0400
 Birth: 2020-06-11 13:31:21.170568000 -0400

stat命令告诉您有关文件的很多信息,包括文件的大小。

答案 7 :(得分:0)

这可能不是最佳选择,但如果上述方法不起作用,您可以这样做:

with open('myfile.txt', 'r') as file:
    data = file.read()[:-1]
with open('myfile.txt', 'w') as file:
    file.write(data)

代码首先打开文件,然后将其内容(最后一个字符除外)复制到字符串data。之后,文件被截为零长度(即清空),并将data的内容保存到文件中,同名。 这与 vins ms 的回答基本相同,只是它不使用 os 包,并且使用了更安全的“with open”语法。如果文本文件很大,可能不建议这样做。 (我写这个是因为上述方法在 python 3.8 中对我来说都不是很好。