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 :

Comparer deux arborescences (+ fichiers)


Sujet :

Python

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut Comparer deux arborescences (+ fichiers)
    Bonjour à tous,

    j'essaye désespérément deux parcourir deux arborescence pour par la suite comparer les fichiers des deux arbo.

    Par exemple j'ai cet arbo :

    c
    --Dos1
    ---Dos11
    -----file1
    -----file2
    ---Dos12
    -----file1

    Et également l'arbo suivante

    d
    --Dos1
    ---Dos11
    -----file1
    -----file2
    ---Dos12
    -----file1

    J'aimerai pouvoir parcourir les deux arbos parallèlement et retourner une erreur si un dossier ou un fichier manque dans l'arbo cible (le 2eme dans mon post).

    Je vous remercie pour votre aide. Bon après midi.

    Cordialement,

    Leniouns

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    vous pouvez utiliser dircmp dans le module filecmp. Des exemples d'utilisations sont par exemple ici

    Cordialement,
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Merci de ton aide.

    Je voulais savoir tout de même si ce module permettait de comparer tous les fichiers dans 2 répertoires et sous répertoires.
    Suivant mon exemple plus haut, est-ce que le module me permettra de comparer tous les fichiers entre eux ?

    Merci de votre aide à tous

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Qu'est ce qui dans la documentation ou les exemples fournis permettent d'en douter? Avez vous essayé d'adapter un des exemples à votre cas? Quels problèmes rencontrez vous? Où est votre code?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Voici mon code :

    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
    def cmpDir(self, directoryLocal, directoryNas): 
            '''
            Compare récursivemment les fichiers présents dans les différents répertoire
            '''
            # Determine the items that exist in both directories
            d1_contents = set(os.listdir(directoryLocal))
            d2_contents = set(os.listdir(directoryNas))
            common = list(d1_contents & d2_contents)
            common_files = [ f 
                    for f in common 
                    if os.path.isfile(os.path.join(directoryLocal, f))
                    ]
            print("Common files:"), common_files
     
            # Compare the directories
            match, mismatch, errors = filecmp.cmpfiles(directoryLocal, 
                                               directoryNas, 
                                               common_files)
            print('Match:'), match
            print('Mismatch:'), mismatch
            print('Errors:'), errors

    Avec les répertoires comme ceux de mon premier post. Cependant mes listes sont vides (common files, match etc.)

    Merci de ton aide

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Je ne vois pas d'utilisation de "dircmp" dans ce code là.

    Pourquoi ne pas simplement commencer par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    filecmp.dircmp(a, b).report_full_closure()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Merci de ton aide. Cette fonction est récursive il me semble. Il y a moyen ensuite de récupérer la liste des fichiers qui diffèrent ? Je te remercie

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Leniouns Voir le message
    Merci de ton aide. Cette fonction est récursive il me semble. Il y a moyen ensuite de récupérer la liste des fichiers qui diffèrent ? Je te remercie
    Il y a toujours "moyen" de coder "un truc".
    Le pire étant de faire des "cut&paste" dans le code source.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Quand j'écris ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    cmp = filecmp.dircmp(directoryLocal, directoryNas)
            cmp.report_full_closure()
            print(cmp.left_only)
    Il m'affiche seulement le dernier fichier de left_only. Il me les affiche pas tous il me semble

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    .report_full_closure() devrait afficher (plus que) ce que vous voulez.

    C'est une fonction "récursive" qui crée des contextes de "cmpdir" pour chaque "paire" de répertoires à comparer. Lorsque vous écrivez "print(cmp.left_only)" vous ne récupérez que la "racine", pas les fils.

    Le code de .report_full_closure est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        def report_full_closure(self): # Report on self and subdirs recursively
            self.report()
            for sd in self.subdirs.values():
                print()
                sd.report_full_closure()
    L'implémentation de cmpdir ne permettant pas une surcharge par héritage, vous pouvez faire une fonction "semblable":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def report_full(ctx):
        report(ctx)
        for sd in ctx.subdirs.values():
            report_full(sd)
    Et écrire une fonction "report" qui récupère la comparaison "courante" pour en sortir ce que vous voulez.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Merci de ton aide mais à quoi correspond ctx ?

    sd = subdirectory ?

    Tu me suggère donc de créer une fonction report_full et report (qui ressemble fortemment à report de filecmp avec seulement les traitements que je désire).

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Leniouns Voir le message
    à quoi correspond ctx ?
    sd = subdirectory ?
    Comme vous pouvez le constater, la fonction report_full(ctx) est fortement inspirée de la méthode report_full_closure(self) => ctx étant l'équivalent de "self", il ne peut qu'être une instance de filecmp.dircmp.
    En gros, report_full s'appelle via un report_full(filecmp.dircmp(a, b)))

    sd est une instance de dircmp.
    .subdirs est un dict dont les "keys" sont les répertoires "communs" aux deux arborescences "à comparer" et les "values" des instances de dircmp construites pour comparer.

    Tu me suggère donc de créer une fonction report_full et report (qui ressemble fortemment à report de filecmp avec seulement les traitements que je désire).
    La sortie existante ne vous convenant pas, à vous de coder ce bout là.
    Maintenant si vous voulez tout ré-écrire...
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Désolé je suis vraiment débutant en Python.

    Ce que je ne comprend pas c'est que lorsque je créer une fonction le premier paramètre doit forcemment être self... Du coup je ne peux pas faire ce que tu me proposes

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Leniouns Voir le message
    Ce que je ne comprend pas c'est que lorsque je créer une fonction le premier paramètre doit forcemment être self... Du coup je ne peux pas faire ce que tu me proposes
    Le premier paramètre d'une fonction est ce que vous voulez (et il peut être optionnel).
    Le premier paramètre d'une méthode est "l'objet" auquel il va s'appliquer et il n'est pas optionnel. La convention est de nommer ce paramètre "self" (ou "cls" s'il s'agit d'une méthode de classe).
    Par défaut, les méthodes sont définies dans le "block" de construction de la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class A:
         def m(self): pass
    Mais vous pourriez écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def _m(self): pass # la chose est "fonction"
    class A:
         m = _m # elle devient "méthode"
    Ce qui change c'est "l'écriture de l'appel à":
    • la méthode: a.m()
    • la fonction: _m(a)

    A l'intérieur de "_m", le premier paramètre appelé "self" pourra jouer le même rôle que la chose soit fonction ou méthode.
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    D'accord.

    Par contre je suis désolé mais je ne vois pas du tout comment faire pour récupérer tous les fichiers qui diffèrent entre les deux répertoires.

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Leniouns Voir le message
    Par contre je suis désolé mais je ne vois pas du tout comment faire pour récupérer tous les fichiers qui diffèrent entre les deux répertoires
    "Il suffit" d'écrire la fonction report(ctx) correspondant à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def report_full(ctx):
        report(ctx)
        for sd in ctx.subdirs.values():
            report_full(sd)
    
    report_full(filecmp.dircmp(a, b)
    Le plus simple étant de partir d'un "cut&paste" du source.
    Vous avez tout.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Bonjour je suis entrain de travailler sur une autre méthode qui me parait plus accessible pour mon niveau.

    Voici le code que j'ai récupéré permettant de récupérer une liste de tous les fichiers présents dans une arborescence :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def listdirectory(path): 
        fichier=[] 
        l = glob.glob(path+'\\*') 
        for i in l: 
            if os.path.isdir(i): fichier.extend(listdirectory(i)) 
            else: fichier.append(i) 
        return fichier
    Par la suite pour récupérer les deux listes des deux arbo je fait comme ceci :

    Dans mon main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    local = "c:\\pat\\PDGS(ESRIN-FTP)"
        nas1 = "d:\\PDGS(ESRIN-FTP)"
        nas  = nas.NAS()
        nas.initialize(nas1, nas1)
        nas.cmpDir(local,nas1)

    Dans NAS :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def cmpDir(self, directoryLocal, directoryNas):
            '''
            Compare les fichiers des deux répertoires
            '''
            local = directoryLocal
            nas = directoryNas
            listLocal = directory.listdirectory(local) 
            listNas = directory.listdirectory(nas)
            for localFile in listLocal:
                print(os.path.splitdrive(localFile))
            print(str(listLocal))
            print(str(listNas))

    Ainsi je récupère les chemins de tous les fichiers contenus dans les deux arbo.
    Maintenant j'aimerai comparer les fichiers (absence, bon chemin, bonne taille...). Mais avant cela il faudrait que pour le disque c: j'enlève des chemins c:\pat et pour le chemin d: il faut que j'enlèbe le chemin d:\

    J'ai vu que la fonction os.path.splitdrive(path) renvoit un couple contenant le disque et ensuite le chemin. Comment fait on pour récupérer un élément d'un couple ? Cela marche-t-il comme pour les listes ?

    EDIT : En effet cela marche comme les listes. Pour récupérer j'ai juste à faire couple[1].

    Sinon avez vous des idées une fois les deux listes obtenues pour comparer les fichiers ? Et comment faire pour enlever le "pat" du premier répertoire? Merci

    Je vous remercie de votre aide.

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Le code de filecmp fait déjà tout çà.

    Vous pouvez souhaiter le ré-écrire pour mieux le "comprendre" mais comment espérez arriver à faire à peut prêt la même chose si vous n'êtes pas encore capable de le lire et le comprendre?

    Récupérer et adapter un peut l'existant de la méthode report pour lui faire afficher les fichiers "différents" se réduit à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def report(self): # Print a report on the differences between a and b
        # Output format is purposely lousy
        print('diff', self.left, self.right)
        if self.left_only:
            self.left_only.sort()
            print('Only in', self.left, ':', self.left_only)
        if self.right_only:
            self.right_only.sort()
            print('Only in', self.right, ':', self.right_only)
    Si vous voulez "stocker" les noms complets des fichiers différents dans les deux arborescences, vous pouvez éventuellement créer deux listes "globales"
    left et right et y ajouter les fichiers trouvés.

    Bon courage
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2010
    Messages : 434
    Points : 94
    Points
    94
    Par défaut
    Merci encore une fois de t'occuper de mon problème.

    Voici mon code :

    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
    def report(ctx): # Print a report on the differences between a and b
        # Output format is purposely lousy
        localDiff = []
        nasDiff = []
        #print('diff', ctx.left, ctx.right)
        if ctx.left_only:
            ctx.left_only.sort()
            #print('Only in', ctx.left, ':', ctx.left_only)
            localDiff.append(str(ctx.left) + "\\" + ctx.left_only[0])
            print(str(localDiff))
     
        if ctx.right_only:
            ctx.right_only.sort()
            #print('Only in', ctx.right, ':', ctx.right_only)
            nasDiff.append(str(ctx.right) + "\\" + ctx.right_only[0])
            print(str(nasDiff))
     
    def report_full(ctx):
        report(ctx)
        for sd in ctx.subdirs.values():
            report_full(sd)
    J'ai bien les deux listes avec les fichiers qui diffèrent soit à gauche soit à droite. Par contre j'ai une petite question. Comment faire justement pour retourner ces deux listes ? Merci.

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Comment faire justement pour retourner ces deux listes ?
    Vous les déclarez en variables globales.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def report(ctx): # Print a report on the differences between a and b
         ...
     
    def report_full(ctx):
        report(ctx)
        for sd in ctx.subdirs.values():
            report_full(sd)
     
    localDiff = []
    nasDiff = []
    report_full(filecmp.dircmp(a, b)
    On pourrait faire plus propre en emballant le tout dans une classe ou en les passant en paramètre aux fonctions report_full et report...
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/04/2013, 10h39
  2. [Bat] comparer deux arborescences d'un NAS
    Par Josh99 dans le forum Scripts/Batch
    Réponses: 5
    Dernier message: 24/01/2012, 23h04
  3. Comparer deux arborescences
    Par kalume dans le forum Langage
    Réponses: 1
    Dernier message: 09/08/2010, 15h08
  4. diff : comparer deux arborescences
    Par jsjohn dans le forum Administration système
    Réponses: 2
    Dernier message: 02/01/2010, 17h33
  5. Réponses: 5
    Dernier message: 09/01/2005, 19h54

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