Python - Supprimer le dernier caractère dans le fichier

Après avoir regardé partout sur Internet, j'en suis arrivé là.

Disons que j'ai déjà fait un fichier texte qui lit: Hello World

Eh bien, je veux supprimer le tout dernier caractère (dans ce cas d) de ce fichier texte.

Alors maintenant, le fichier texte devrait ressembler à ceci: Hello Worl

, Mais je n'ai aucune idée de comment faire cela.

Tout ce que je veux, plus ou moins, est une seule fonction de retour arrière pour les fichiers texte sur mon disque dur.

Cela doit fonctionner sur Linux car c'est ce que je suis utiliser.

26
demandé sur quasoft 2013-09-17 22:34:15

4 réponses

Utiliser file.seek() pour chercher 1 position à partir de la fin, puis utilisez file.truncate() pour enlever le reste du fichier:

with open(filename, 'rb+') as filehandle:
    filehandle.seek(-1, os.SEEK_END)
    filehandle.truncate()
48
répondu Martijn Pieters 2013-09-17 18:59:26

La réponse acceptée de Martijn est simple et fonctionne, mais ne tient pas compte des fichiers texte avec:

  • encodage UTF-8 contenant des caractères non anglais (qui est l'encodage par défaut pour les fichiers texte en Python 3)
  • un caractère newline à la fin du fichier (qui est la valeur par défaut dans les éditeurs Linux comme vim ou gedit)

Si le fichier texte contient des caractères non anglais, aucune des réponses fournies jusqu'à présent ne travail.

Ce qui suit est un exemple, qui résout les deux problèmes, ce qui permet également de supprimer plus d'un caractère de la fin du fichier:

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

Comment ça marche:

  • Lit uniquement les derniers octets d'un fichier texte encodé en UTF-8 en mode binaire
  • itère les octets en arrière, à la recherche du début D'un caractère UTF-8
  • Une fois qu'un caractère (différent d'un saut de ligne) est trouvé, renvoyez-le comme dernier caractère dans le texte fichier

Exemple de fichier texte - bg.txt:

Здравей свят

Comment utiliser:

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

Sorties:

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

Cela fonctionne avec les fichiers encodés UTF-8 et ASCII.

4
répondu quasoft 2017-02-04 13:36:36
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

Assurez-vous d'utiliser le mode binaire sous windows puisque la ligne de fichier Unix se terminant beaucoup renvoient un nombre de caractères illégal ou incorrect.

2
répondu dawg 2013-09-17 18:59:55

Voici un moyen sale (effacer et recréer)... Je ne conseille pas d'utiliser ceci, mais, il est possible de faire comme ça ..

x = open("file").read()
os.remove("file")
open("file").write(x[:-1])
0
répondu vins mv 2017-08-27 09:23:03