IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Supprimer 7 dernières lignes d'un fichier et écrire au début de ce fichier


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Par défaut Supprimer 7 dernières lignes d'un fichier et écrire au début de ce fichier
    Bonjour,

    Voilà j'ai écrit un programme qui doit me permettre d'ajouter 7 lignes dans un fichier si le dernier enregistrement dans ce fichier (qui doit correspondre au 7 premières lignes de mon fichier) est différent de celui que je veux y inscrire.
    En plus de ça, je ne veux pas avoir plus de dix enregistrements dans mon fichier donc, si j'en ai déjà dix et que l'enregistrement que je veux inscrire n'est pas le même que le dernier alors je veux supprimer les 7 dernières ligne de mon fichier et écrire mon enregistrement (7 lignes) au début de mon fichier.

    Mon problème est que je n'est pas trouvé comment faire pour supprimer les 7 dernières lignes de mon fichier et écrire mon enregistrement au début du fichier. Mon fichier étant ouvert en mode "append" j'ai pensé à utiliser la fonction seek() mais je reste bloqué là.

    Est-ce que quelqu'un aurait une petite idée ? (Désolé pour le pavé d'avant mais je voulais être le plus clair possible)

    Voici mon bout de programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import re
     
    # Fonction qui va récupérer les 7 lignes que je vais éventuellement insérer dans mon fichier
    def parseCRMON(file_crmon):
        contenu = []
        derupdate = ""
        current = ""
        serveur = ""
        statut = ""
        serv_stat = ""
     
        regex1 = "(\w+\s\w+\:\s\w+\s\w+\s\d+\s\d+\:\d+\:\d+\s\d+)"
        regex2 = "(Current\:\s\w+)"
        regex3 = "Serveur\s(\w+)\s\(\w+\-\w+\-\w+\-\w+\-\w+\)\:\s(\w+)"
     
        pattern1 = re.compile(regex1)
        pattern2 = re.compile(regex2)
        pattern3 = re.compile(regex3)
     
        fh = open("file_crmon","r")
        lignes = fh.readlines()
     
        for ligne in lignes:
            ligne = ligne.rstrip("\n")
            found1 = pattern1.search(ligne)
            found2 = pattern2.search(ligne)
            found3 = pattern3.search(ligne)
     
            if found1:
                derupdate = found1.group(1)
                contenu.append(derupdate)
     
            if found2:
                current_dc = found2.group(1)
                content.append(current_dc)
     
            if found3:
                serveur = found3.group(1)
                statut = found3.group(2)
                serv_stat = "%s: %s" % (serveur, statut)
                contenu.append(serv_stat)
     
        fh.close()
        return contenu
     
    #Fonction qui va vérifier que je peux écrire mon enregistrement en le comparant avec le premier enregistrement de mon fichier, l'écrire au début du fichier si c'est bon et supprimer les sept dernières lignes
    def addEntry(self, fichier, compare_table):
        donnees_liste1 = self.compare_table
        donnees_liste2 = []
     
        fih = open("fichier","a")
        lignes = fih.readlines()
     
        for ligne in lignes:
            ligne = ligne.rstrip("\r")
            donnees_liste2.append(ligne)
     
        if donnees_liste1[1] == donnees_liste2[1]:
            if donnees_liste1[2] == donnees_liste2[2]:
                if donnees_liste1[3] == donnees_liste2[3]:
                    if donnees_liste1[4] == donnees_liste2[4]:
                        if donnees_liste1[5] == donnees_liste2[5]:
                            if donnees_liste1[6] == donnees_liste2[6]:
                                fih.close()
        else:
            if len(donnees_liste2) >= 64:

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Salut,



    J’ai mis un petit coup de plumeau dans ton code.



    J’ai notamment remplacé f.readlines() par f.read().splitlines() car splitlines() ne conserve pas les fins de lignes ’\n’ et ’\r’ , et ça aide !



    Si ma est un MatchObject, ma.groups() est un tuple de tous les groupes. S’il n’y a qu’un groupe, c’est un tuple à un seul élément, et si on fait ’: ’.join(ma.groups()) dessus, ça ne change en fait rien car ’: ’.join( ) ne fait que lier des éléments, et s’il n’y en a qu’un, ça ne lie rien du tout.
    Ainsi avec cette “astuce“, on peut rendre générique le traitement de tes différents cas, quel que soit le nombre de groupes.



    Sans doute y aura-t-il des erreurs et des choses que tu ne saisiras pas N’hésite pas a demander.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import re
     
    # Fonction qui va récupérer les 7 lignes que je vais
    # éventuellement insérer dans mon fichier
    def parseCRMON(file_crmon):
        contenu = []
     
        for i,RE in enumerate("(\w+\s\w+\:\s\w+\s\w+\s\d+\s\d+\:\d+\:\d+\s\d+)",
                              "(Current\:\s\w+)",
                              "Serveur\s(\w+)\s\(\w+\-\w+\-\w+\-\w+\-\w+\)\:\s(\w+)"):
            pattern[i] = re.compile(RE)
     
        fh = open("file_crmon","r")
        lignes = fh.read().splitlines()
        fh.close()
     
        found = [0,0,0]
        for ligne in lignes:
            for i in xrange(3):
                found[i] = pattern[i].search(ligne)
                if found[i]:
                    contenu.append(": ".join(found[i].groups()))
        return contenu
     
     
    def addEntry(self, fichier, compare_table):
        donnees_liste1 = self.compare_table
     
        fih = open("fichier","a")
        donnees_liste2 = fih.read().splitlines()
     
        if donnees_liste1[1] == donnees_liste2[1]:
            if donnees_liste1[2:7] == donnees_liste2[2:7]:
                fih.close()
        else:
            if len(donnees_liste2) >= 64:


    Remarque concernant ton code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        if donnees_liste1[1] == donnees_liste2[1]:
            if donnees_liste1[2] == donnees_liste2[2]:
                if donnees_liste1[3] == donnees_liste2[3]:
                    if donnees_liste1[4] == donnees_liste2[4]:
                        if donnees_liste1[5] == donnees_liste2[5]:
                            if donnees_liste1[6] == donnees_liste2[6]:
                                fih.close()
    Si, par exemple, donnees_liste1[3] == donnees_liste2[3] est False , alors il n’y aura pas exécution de fih.close() mais comme on n'est pas dans la première évaluation
    donnees_liste1[1] == donnees_liste2[1]
    le programme ne passera pas au else:

    Est-ce vraiment ce que tu veux obtenir ?

    En tous cas, j'ai respecté cet effet en gardant deux lignes if.

    Sinon, il se peut que ce soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        if donnees_liste1[1:7] == donnees_liste2[1:7]:
            fih.close()
    qui convienne en fait.



    Regarde aussi de près les indices.
    donnees_liste1[1:7] est la portion de donnees_liste qui commence au deuxième élément (index 1) et se termine avec le 6ième compris(index 6)



    Désolé pour le pavé d'avant mais je voulais être le plus clair possible
    Non c'est Ok, c'est mieux quand il y a des explications pour bien comprendre.





    PS

    J’ai bien conscience que je n’ai pas répondu à ta question.
    Je vais regarder ça maintenant.

    En fait, il y a deux solutions: poursuivre dans la voie que tu as prise: analyse de lignes.

    Il y a en a une autre.
    Il n’y a pas de lignes dans un fichier. Un fichier n’est qu’une suucession de caractères parmi lesquels les fins de lignes ’\n’ et ’\r\n’ déclenchent, lors d’un affichage, des retours à la ligne à l’écran. Mais dans le fichier, y a que des caractères.
    En conséquence on peut traiter un problème rien qu’avec des regex, sans mettre les fichiers dans des listes et tous les enquiquinements de leur traitement après.



    Mais un tuyau en attendant la suite: pour trafiquer dans un fichier avec des seek() et des tell() , et pouvoir aussi bien y écrire que le lire, il faut l’ouvrir en ’rb+’



    Précise ta version de Python stp

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Par défaut
    Merci pour ton aide eyquem, c'est vrai que ton code est beaucoup plus propre . En tout cas ça va me permettre d'avancer un peu je l'espère.

    Au fait, oui c'est bien ce code là que je voulais obtenir (ça m'aurait pas effleuré de le faire comme ça, mais c'est exactement ce que je voulais) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if donnees_liste1[1:7] == donnees_liste2[1:7]:
        fih.close()
    Ma version de python est la 2.5.4.

  4. #4
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Je vous renvoie à cette discussion:
    http://www.developpez.net/forums/d42...-fichier-lire/
    Où il est clairement établi qu'il est inutile et même nuisible de lire un fichier dans son intégralité pour en connaître le nombre de lignes.
    Je propose donc de commencer à déterminer le nombre N de lignes du fichier.
    Soit alors M=N-7
    Lire ensuite (une à une) les M premières lignes et les écrire dans un autre fichier. Fermer le second fichier et le renommer du nom du premier.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Je vous renvoie à cette discussion:
    http://www.developpez.net/forums/d42...-fichier-lire/
    Où il est clairement établi qu'il est inutile et même nuisible de lire un fichier dans son intégralité pour en connaître le nombre de lignes.
    Je propose donc de commencer à déterminer le nombre N de lignes du fichier.
    Soit alors M=N-7
    Lire ensuite (une à une) les M premières lignes et les écrire dans un autre fichier. Fermer le second fichier et le renommer du nom du premier.
    Merci pour l'info. Je vais voir cette possibilité.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Samb95,



    Si tu pouvais donner un exemple comportant:
    - fichier
    - un bloc de 7 lignes à ajouter
    - les critères qui font qu’un bloc de 7 lignes est identique ou différent du dernier bloc enregistré = les 7 premières lignes du fichier

    J’ai plusieurs idées à tester, c’est mieux d’avoir du concret.



    Regarde aussi du coté de la persistance:
    http://docs.python.org/release/2.5.4...rsistence.html
    Pourquoi ne pas enregistrer une liste de dix éléments , chaque élément = 1 bloc de 7 lignes.

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Par défaut
    Salut,

    je propose ceci (non testé car pas de données de test et pas envie d'en écrire).

    Je décorrèle la manipulation de données de la lecture et l'écriture du fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    def insert_infos(infos, new_info, max_length=10):
        """
        Puts 'new_info' at the end of 'infos' only if it is not already present at
        the beginning.
        Keeps length of 'infos' less or equal to 'max_length' by keeping only the
        most recent (i.e. the 'max_length' last ones).
        """
        if infos[0] != new_info:
            infos.append(new_info)
        if len(infos) > max_length:
            infos = infos[-max_length:]
        return infos
     
    def read_file(filename, seq_length=7):
        """
        Reads a file by blocks of 'seq_length' lines.
        """
        infos = []
        with open(filename) as f:
            for i, line in enumerate(f):
                line = line.strip()
                if i % seq_length == 0:
                    infos.append([])
                infos[-1].append(line)
        return infos
     
    def write_file(filename, infos):
        """
        Writes 'infos' (list of lists of strings) into 'filename'.
        """
        with open(filename, mode='w') as f:
            for info in infos:
                f.write('\n'.join(info) + '\n')
    Note : Je viens juste de voir le message d'Eyquem, qui apparemment a eu la même idée que moi pour la liste.
    Du coup, je constate qu'il faut peut-être retravailler l'égalité de 2 blocs.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Supprimer les dernières lignes d'un fichier
    Par eleana dans le forum Shell et commandes GNU
    Réponses: 16
    Dernier message: 03/11/2017, 10h55
  2. [XL-2007] Supprimer la dernière ligne vide d'un fichier txt avec vba
    Par nyepalo dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 26/06/2015, 09h31
  3. [Batch] Supprimer la dernière ligne d'un fichier texte
    Par pol2095 dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 17/03/2015, 22h07
  4. Supprimer la dernière ligne vide d'un fichier txt
    Par petit rabot dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 08/12/2011, 12h15
  5. Réponses: 14
    Dernier message: 30/03/2005, 21h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo