Подтвердить что ты не робот

Python - удалить последний символ в файле

После просмотра по всему Интернету я пришел к этому.

Скажем, я уже сделал текстовый файл, который гласит: Hello World

Ну, я хочу удалить из этого текстового файла самый последний символ (в данном случае d).

Итак, теперь текстовый файл должен выглядеть так: Hello Worl

Но я понятия не имею, как это сделать.

Все, что я хочу, более или менее, - это одна функция backspace для текстовых файлов на моем жестком диске.

Это должно работать на Linux как на то, что я использую.

4b9b3361

Ответ 1

Используйте file.seek(), чтобы искать 1 позицию с конца, затем используйте file.truncate(), чтобы удалить оставшуюся часть файла:

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

Ответ 2

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

Обязательно используйте двоичный режим для окон, так как строка файла Unix, заканчивающаяся многими, возвращает незаконный или неправильный символ.

Ответ 3

Принятый ответ Martijn прост и работает, но не учитывает текстовые файлы:

  • кодировка UTF-8, содержащая неанглийские символы (которая является кодировкой по умолчанию для текстовых файлов в Python 3)
  • один символ новой строки в конце файла (который по умолчанию используется в редакторах Linux, таких как vim или gedit)

Если текстовый файл содержит неанглийские символы, ни один из представленных ответов не будет работать.

Далее следует пример, который решает обе проблемы, что также позволяет удалить более одного символа из конца файла:

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

вот грязный способ (стереть и воссоздать)... я не советю использовать это, но это возможно сделать так.

x = open("file").read()
os.remove("file")
open("file").write(x[:-1])