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 :

Déplacer tous les fichiers de plusieurs répertoires vers un répertoire cible


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 58
    Par défaut Déplacer tous les fichiers de plusieurs répertoires vers un répertoire cible
    Bonjour,
    J'ai besoin de déplacer tous les fichiers de plusieurs répertoires vers un répertoire cible.
    par exemple :
    Repertoire A contient FichA, FichB, FichC
    Repertoire B contient FichD, FichE, FichF
    Repertoire C contient FichG, FichH, FichI
    Je voudrai que le répertoire cible contienne les fichiers :

    FichA, FichB, FichC, FichD, FichE, FichF, FichG, FichH, FichI

    J'ai d'abord voulu utiliser shutil.copytree mais ça ne convient pas car il ne faut pas que le fichier cible existe.
    Pouvez-vous m'indiquer comment faire ou me diriger vers une piste ?
    Merci de votre aide

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà un petit code sans prétention qui fait une copie récursive d'un répertoire vers un autre et qui crée les répertoires manquants quand c'est nécessaire. A noter qu'il ne crée pas les répertoires vides.

    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
    # -*- coding: utf-8 -*-
     
    import os
    from glob import iglob
    import shutil
     
    def copytree2(repertoire1, repertoire2, affiche=False):
        """copie récursive des fichiers du répertoire 1 vers 2
           crée les répertoires absents de 2 quand c'est nécessaire
        """
        # normalise les chemins et calcule leurs longueurs
        repertoire1 = os.path.abspath(os.path.expanduser(repertoire1))
        lgrep1 = len(repertoire1)
        repertoire2 = os.path.abspath(os.path.expanduser(repertoire2))
        lgrep2 = len(repertoire2)
     
        i = 0
        for nfc1 in iglob(os.path.join(repertoire1, "**", "*"), recursive=True):
            if not os.path.isdir(nfc1):
                # nfc1 est un fichier (avec son chemin absolu)
                i += 1
                nfc2 = repertoire2 + nfc1[lgrep1:] # calcule le chemin dest.
                try:
                    shutil.copy2(nfc1, nfc2) # copie fichier répertoire 1 => 2 
                except IOError:
                    os.makedirs(os.path.dirname(nfc2)) #crée répertoires absents
                    shutil.copy2(nfc1, nfc2) # copie fichier repépertoire 1 => 2  
     
                if affiche:
                    print("{} copie: {} ===> {}".format(i, nfc1, nfc2))
    On pourrait, bien sûr, ajouter plein de choses pour qu'il soit plus intelligent:
    - ajouter des motifs wildcard pour qu'il ne copie que les fichiers voulus (".py", *.pyw, ...)
    - ajouter des motifs wildcard pour qu'il évite de recopier certains répertoires
    - ajouter des conditions de copie pour ne recopier que les fichiers de 1 absents ou plus récents que ceux de 2, ce qui permettrait de faire des sauvegardes "incrémentales".
    - etc...

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 58
    Par défaut
    Bonsoir tyrtamos,

    Je me suis abimé les yeux à essayer de comprendre le code que tu as mis en réponse à ma question.
    J'ai bien peur de ne pas avoir le niveau nécessaire.
    Pourrai tu avoir la gentillesse de le commenter ?

    Le peu que j'ai compris c'est que tout le code est contenu dans la fonction copytree2 mais je ne vois pas où cette fonction est appelée.

    Merci


    Bonsoir wiztricks,

    Tout d'abord je voudrai rectifier une erreur. Dans la phrase :
    J'ai d'abord voulu utiliser shutil.copytree mais ça ne convient pas car il ne faut pas que le fichier cible existe.
    Il s'agit de répertoire et non pas fichier.


    Par curiosité, qu'est ce qui vous pousse à coder çà?
    J'ai lancé un logiciel de récupération de données suite à un crash sur un disque dur.
    Après analyse du disque le logiciel a créé 472 répertoires contenant chacun 500 fichiers de toutes sortes (textes, images, audio, vidéos, exécutables etc...).
    Il semblerai que dans les 472 répertoires il n'y a que des fichiers et pas de sous-répertoire.
    J'aimerai rassembler tous ces fichiers dans un seul répertoire.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2010
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 58
    Par défaut
    re,

    Finalement j'ai pu faire tourner le code en ajoutant cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    copytree2("F:\essai", "F:\Cible", True)
    Mais ça ne fonctionne pas comme je le voudrai.
    En effet après l’exécution du code, on obtient dans le répertoire cible tous les répertoires alors que ce que je voudrai ce ne sont que les fichiers.

    Pour le test j'ai créé (sous F:\Essai) 3 répertoires (Rep1, Rep2, Rep3) et 1 répertoire Cible
    Dans chaque répertoire j'ai créé 3 fichiers texte.
    Rep1 contient Fic1, Fic2, Fic3
    Rep2 contient Fic4, Fic5, Fic6
    Rep3 contient Fic7, Fic8, Fic9
    Au final j'aimerai obtenir :
    Cible contient Fic1, Fic2, Fic3, Fic4, Fic5, Fic6, Fic7, Fic8, Fic9

    Est-ce possible ?

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Oui, je ne m'étais intéressé qu'à une version de copytree qui n'avait pas la même contrainte concernant l’existence du répertoire destinataire. Voilà une nouvelle version qui, cette fois lit bien de façon récursive le répertoire source, mais écrit tout dans le répertoire destination sans créer les sous-répertoires.

    Il faut tout de même ajouter une option "ecrase" qui, si False, empêchera à un fichier d'être copié s'il existe déjà dans le répertoire destination. Il est probable que le problème ne se pose pas chez toi.

    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
    # -*- coding: utf-8 -*-
     
    import os
    from glob import iglob
    import shutil
     
    #############################################################################
    def copytree2rep(repertoire1, repertoire2, ecrase=True, affiche=False):
        """copie récursive des fichiers du répertoire 1 vers un répertoire 
           contenant tous les fichiers sans sous-répertoire
        """
        # normalise les chemins
        repertoire1 = os.path.abspath(os.path.expanduser(repertoire1))
        repertoire2 = os.path.abspath(os.path.expanduser(repertoire2))
     
        if not os.path.exists(repertoire2):
            os.makedirs(repertoire2) # crée le répertoire destinataire si absent
     
        i = 0
        for nfc1 in iglob(os.path.join(repertoire1, "**", "*"), recursive=True):
            if not os.path.isdir(nfc1):
                # nfc1 est un fichier (avec son chemin absolu)
     
                # calcule le chemin destinataire absolu du fichier nfc1
                nfc2 = repertoire2 + os.sep + os.path.basename(nfc1)
     
                # copie nfc1 vers le répertoire destinataire
                if not os.path.exists(nfc2) or ecrase:
                    i += 1
                    shutil.copy2(nfc1, nfc2)
                    if affiche:
                        print("{} copie: {} ===> {}".format(i, nfc1, nfc2)) 
                else:
                    # le fichier nfc1 existe déjà dans rep2 et on refuse de l'écraser
                    if affiche:
                        print("Non copié: {}".format(nfc2))
    Voilà pour l'exécution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    repertoire1 = r"F:\Essai"
    repertoire2 = r"F:\EssaiDest"
     
    copytree2rep(repertoire1, repertoire2, True, True)
    Ce petit code taillé pour le problème posé devrait être complété pour être utilisé dans un contexte plus large. Par exemple, il ne prend pas en compte les problèmes de droits qu'on peut trouver surtout sous Linux ou MacOS qui empêcherait de lire le contenu d'un fichier et donc de le copier. De même iglob devant un répertoire dans lequel on ne peut pas rentrer n'en tient pas compte et n'en dit rien. Pour connaître ces erreurs de droits, il faudrait utiliser plutôt os.walk et ajouter un try.. except... pour les copies impossibles sans lequel le programme planterait à la 1ère erreur. De même il n'est pas prévu une option pour savoir si on doit suivre les liens symboliques ou pas. Mais ça complique le code inutilement ici...

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Citation Envoyé par coleoptere Voir le message
    J'ai d'abord voulu utiliser shutil.copytree mais ça ne convient pas car il ne faut pas que le fichier cible existe.
    Si le fichier cible existe déjà, il faut déjà décider ce qu'on fait dans ce cas là pour savoir si on écrase l'existant ou si on crée une copie "à côté".

    La documentation de shutil.copytree donne un tas d'options à utiliser dans ce cas là (et même un code de copytree à modifier au cas où).

    Citation Envoyé par coleoptere Voir le message
    J'ai besoin de déplacer tous les fichiers de plusieurs répertoires vers un répertoire cible.
    C'est en général une opération "ponctuelle", un rangement de printemps qu'on peut faire assez facilement à coup de clics sur son file explorer.

    Par curiosité, qu'est ce qui vous pousse à coder çà?

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

Discussions similaires

  1. [AC-2013] Déplacer tous les fichiers Excel vers un autre répertoire
    Par totor92290 dans le forum IHM
    Réponses: 2
    Dernier message: 06/06/2018, 14h40
  2. Réponses: 2
    Dernier message: 13/12/2009, 22h12
  3. [Batch] Déplacer tous les fichiers au même niveau /supp. arbo.
    Par Rodrigue dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 04/09/2009, 10h05
  4. Copier tous les fichiers d'un répertoire vers un autre
    Par papilou86 dans le forum Langage
    Réponses: 1
    Dernier message: 09/09/2006, 01h02
  5. Réponses: 4
    Dernier message: 24/09/2004, 10h17

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