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 :

Récupérer certaine lignes d'un fichier


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Par défaut Récupérer certaine lignes d'un fichier
    Bonjour à tous,

    Je me suis remis à ce langage abandonné depuis un certain temps.
    Mon problème est le suivant :
    Dans un fichier texte, je désire récupérer certaines lignes. Ces parties de texte sont délimité par deux balises /SPOOL et /END-SPOOL
    J'ai donc cherché le n° de lignes de ces balises (il y en a deux de chaques) et il me faut récupérer le texte entre ces deux balises pour les copier dans un nouveau fichier.

    Voici le début :
    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
     
    f = open('QI-500800.txt', 'r')
    line = f.readline().decode('utf-8')
     
    i = 1
    listeSpool = []
    for line in iter(f):
    	if line[0:6] == "/SPOOL":
    		print line,
    		listeSpool.append(i)
    	if line[0:10] == "/END-SPOOL":
    		print line,
    		listeSpool.append(i)
     
    	i = i + 1
     
    print listeSpool
    f.close()
    Suis-je dans la bonne direction et pouvez-vous m'éclairer ?
    Merci d'avance.
    Pierre

  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
    Bonjour et bienvenue dans le forum,



    C’est un besoin commun, et régulièrement exposé dans ce forum, que celui que tu exposes.
    Suggestion: chercher les files qui en parlent. C’est instructif de voir des idées diverses à propos d’un même problème connaissant des variations.



    Ceci dit, quelques remarques:

    - for line in iter(f): suffit
    f est son propre itérateur

    - les lignes que tu veux récupérer ne sont pas seulement celles qui contiennent les balises et la suite va être de parcourir les lignes entre les balises et de les recopier, n’est ce pas ?
    Je ne pense pas que ce soit la meilleure façon de faire, mais c’est une façon possible.

    Ton code ne me semble pas trop mal parti.
    Mais maintenant, que comptes tu faire des numéros de lignes ? Tu veux reparcourir le fichier pour arriver jusqu’à la première ligne avec balise et faire à ce moment là le recopiage des lignes qui suivent jusqu’à la balise suivante ?
    Mais pourquoi ne pas déclencher ce recopiage juste après avoir détecté la première balise ? Et te passer d'enregistrer les numéros de lignes.


    Sinon, si tu tiens à repérer des lignes par leur numéro, tu aurais intérêt à mettre les lignes dans une liste:

    Lines = f.readlines()
    les fins de lignes ’\n’ sont conservées

    ou

    Lines = f.read().splitlines()
    les fins de ligne sont éliminées



    Précision stp: il y a 4 lignes avec balises au total ( une /SPOOL, puis une /END-SPOOL, puis à nouveau une /SPOOL, puis une /END-SPOOL) ?



    Précise aussi la version de Python que tu utilises, stp.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Bonjour et bienvenue dans le forum,
    Merci

    Citation Envoyé par eyquem Voir le message
    Ceci dit, quelques remarques:
    - for line in iter(f): suffit
    f est son propre itérateur

    - les lignes que tu veux récupérer ne sont pas seulement celles qui contiennent les balises et la suite va être de parcourir les lignes entre les balises et de les recopier, n’est ce pas ?
    Je ne pense pas que ce soit la meilleure façon de faire, mais c’est une façon possible.
    Je savais que tu allais dire ça

    Citation Envoyé par eyquem Voir le message
    Ton code ne me semble pas trop mal parti.
    Mais maintenant, que comptes tu faire des numéros de lignes ? Tu veux reparcourir le fichier pour arriver jusqu’à la première ligne avec balise et faire à ce moment là le recopiage des lignes qui suivent jusqu’à la balise suivante ?
    Mais pourquoi ne pas déclencher ce recopiage juste après avoir détecté la première balise ? Et te passer d'enregistrer les numéros de lignes.
    OK. Je vois que ta solution est la meilleur. Ca ne sert à rien de faire le travail deux fois.
    Maintenant je doit trouver les syntaxes pour ajouter les lignes concernées dans un nouveau fichier.

    Citation Envoyé par eyquem Voir le message
    Précision stp: il y a 4 lignes avec balises au total ( une /SPOOL, puis une /END-SPOOL, puis à nouveau une /SPOOL, puis une /END-SPOOL) ?
    C'est exactement ça.
    La version python est 2.6
    Merci à toi de me guider

    Pierre

  4. #4
    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
    Si c’est un fichier entièrement nouveau, c’est facile.
    Certains veulent parfois ajouter du texte dans un fichier existant, en plein milieu, et là c’est plus délicat.

    Pour ton cas, a priori ouvre ton nouveau fichier en écriture et transfère les lignes une à une:

    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
    f = open('QI-500800.txt', 'r')
    line = f.readline().decode('utf-8')
    g = open('nouveau fichier','w')
     
    transferer = 0
    #i = 1
    #listeSpool = []
    for line in f:
    	if line[0:6] == "/SPOOL":
                    transferer = 1
    		print line
    		#listeSpool.append(i)
            if transferer==1:
                print line
                g.write(line)
    	if line[0:10] == "/END-SPOOL":
                    transferer = 0
    		print line
    		#listeSpool.append(i)
     
    #print listeSpool
    f.close()

    Je veux m’assurer de bien comprendre:
    les parties de textes que tu veux récupérer et transférer sont toutes les lignes entre deux lignes à balises /SPOOL et /END-SPOOL, y compris les lignes avec les balises, et uniquement ces lignes ?



    NB que je ne maîtrise pas les histoires de encode() et decode()

  5. #5
    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
    Voilà l’autre genre de solution auquel je pense et qui me plaît mieux, personnellement: je traite le fichier pour ce qu’il est, une chaîne de caractères, dans laquelle il y a de ci de là des caractères de fin de lignes, mais qui n’ont pas d’intérêt particulier relativement à un problème tel que celui qui t’occupe. Je dis souvent que sur le disque dur, il n’y a pas de lignes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    f = open('QI-500800.txt', 'r')
    line = f.readline().decode('utf-8')
    ch = f.read()
    f.close()
     
    g = open('nouveau fichier','w')
     
    fin = 0
    while 1:
        deb = ch[fin:].find("/SPOOL")
        fin = ch[fin:].find("/END-SPOOL") + len("/END-SPOOL")
        if deb==-1:  break
        g.write( ch[deb:fin] )

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 067
    Par défaut
    peut-être que c'est ce que tu cherches à faire; mais je suis sûr qu'il doit y avoir une fonction pour simplifier le truc ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def spool(fichier)
           out = ''
    	with open(fichier, 'r') as f :
    		f = f.read()
    		while '/SPOOL' in f :
    			i_start = f.index('/SPOOL')
    			i_end = f.index('/END-SPOOL')
    			out = out+f[i_start+6:i_end]+'\n'
    			f = f[:i_start]+f[i_end+10:]
    		return out
     
    print spool('QI-500800.txt')

  7. #7
    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
    On a la même façon d’envisager la chose, josmiley.


    Cependant j’ai une critique sur ton code:

    l’instruction f = f[:i_start]+f[i_end+10:]
    crée un nouvel objet construit comme somme de f[:i_start] et f[i_end+10:] sur lequel est transféré l’étiquette f. Le problème étant qu’il y a création d’objet, ce qui est plus long que de faire un exploration dans une chaîne stable et unique avec des jeux sur indices, comme je le fais dans mon code.



    De plus, d’un point de vue algorithme, pourquoi se traîner f[:i_start] alors que par définition de i_start, il n’y a pas de balise avant cette position i_start ?

    Et tu vois que si on élimines ce f[:i_start] de l’instruction ci-dessus, il ne reste plus que f[i_end+10:] et on s’aperçoit alors que ce n’est pas la peine d’en faire un nouvel objet à renommer f.

  8. #8
    Membre averti
    Homme Profil pro
    Inscrit en
    Février 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 33
    Par défaut
    Citation Envoyé par josmiley Voir le message
    peut-être que c'est ce que tu cherches à faire; mais je suis sûr qu'il doit y avoir une fonction pour simplifier le truc ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def spool(fichier)
           out = ''
    	with open(fichier, 'r') as f :
    		f = f.read()
    		while '/SPOOL' in f :
    			i_start = f.index('/SPOOL')
    			i_end = f.index('/END-SPOOL')
    			out = out+f[i_start+6:i_end]+'\n'
    			f = f[:i_start]+f[i_end+10:]
    		return out
     
    print spool('QI-500800.txt')
    Ca je comprends ce bien ce code, mais avec ce code je n'ai pas les balises. Et ca c'est embêtant.

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

Discussions similaires

  1. [PowerShell] Comment récupérer certaines lignes d'un fichier pour ensuite s'en servir
    Par Zipper963 dans le forum Scripts/Batch
    Réponses: 5
    Dernier message: 13/12/2012, 15h35
  2. [PowerShell] Récupérer certaines lignes d'un fichier txt dans un autre
    Par TanKer dans le forum Scripts/Batch
    Réponses: 7
    Dernier message: 16/11/2011, 21h31
  3. Lire certaines lignes d'un fichier csv
    Par damdam44 dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 12/05/2008, 11h29
  4. Réponses: 1
    Dernier message: 05/10/2006, 09h56
  5. Supprimer certaines lignes d'un fichier texte
    Par kek_net dans le forum Langage
    Réponses: 2
    Dernier message: 10/04/2006, 11h21

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