web-dev-qa-db-fra.com

Python - Supprime le tout dernier caractère du fichier

Après avoir regardé partout sur Internet, j'y suis arrivé.

Disons que j'ai déjà créé 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 ne sais pas comment faire ça.

Tout ce que je veux, plus ou moins, c'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 j'utilise.

34
user2681562

Utilisez file.seek() pour rechercher 1 position à partir de la fin, puis utilisez file.truncate() pour supprimer le reste du fichier:

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

La réponse acceptée de Martijn est simple et genre d'œuvres, 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 dans Python 3)
  • un caractère de nouvelle ligne à 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 fonctionnera.

Ce qui suit est un exemple qui résout les deux problèmes, ce qui permet également de supprimer plusieurs caractères à 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 vers l'arrière, recherchant le début d'un caractère UTF-8
  • Une fois qu'un caractère (différent d'une nouvelle ligne) est trouvé, renvoyez-le comme dernier caractère du fichier texte

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

Les sorties:

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

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

7
quasoft

Dans le cas où vous ne lisez pas le fichier en mode binaire, où vous n'avez que les autorisations "w", je peux suggérer ce qui suit.

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

Dans ce code ci-dessus, f.seek() n'acceptera que f.tell() b/c vous n'avez pas accès à 'b'. vous pouvez ensuite positionner le curseur au début du dernier élément. Ensuite, vous pouvez supprimer le dernier élément par une chaîne vide.

5
metinsenturk
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 sur Windows car la ligne de fichier Unix se terminant par plusieurs renvoie un nombre de caractères illégal ou incorrect .

4
dawg

voici une façon sale (effacer et recréer) ... je ne conseille pas d'utiliser cela, mais, il est possible de faire comme ça ..

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