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 :

listing recursif de repertoire avec x niveaux


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Août 2008
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 41
    Par défaut listing recursif de repertoire avec x niveaux
    Bonjour,

    Je cherche un moyen de faire un listing recursif de repertoire mais pas à l'infini, sur un nombre de sous niverau donné. style :

    recursList(mypath, 1) -> listing de mypath, mypath/x
    recursList(mypath, 2) -> listing de mypath, mypath/x, mypath/x/x

    une idée ?

  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,

    Oui, c'est facile.

    Au 1er appel de la fonction récursive, on place 2 arguments supplémentaires:

    - le niveau_maxi (=0 par défaut). Si le niveau_maxi=0, cela veut dire: profondeur maxi.

    - le niveau_courant (=1 par défaut). Au 1er appel, on le laisse par défaut.

    la fonction appelle les sous-répertoires seulement: si le niveau maxi est =0 ou si le niveau courant est < au niveau maxi.

    Si les sous-répertoires sont appelés, l'appel récursif passe les arguments: niveau_maxi et niveau_courant+1

    Ok?

  3. #3
    Membre averti
    Inscrit en
    Août 2008
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 41
    Par défaut
    Si t'a un example de code je suis preneur (je comprends bien, mais comment arreter le os.walk ?)

    sinon avec glob, je viens de faire çà qui marche bien :

    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
     
    #!/usr/bin/env python
    #-*- coding: UTF-8 -*-
     
     
    import os, glob
     
    def recursListPath(path, nth = 1):
        list = []
        for i in range (1, nth+1):
            currentpath = path + (i * "/*")
            for name in glob.glob(currentpath):
                list.append(name)
        return list
    #
     
    DirPath = r"C:\Program Files (x86)\Common Files\System"
    list = recursListPath(DirPath, 2)
    print "number of item:", len(list)
    for item in list:
        if os.path.isfile(item):
            print "_file:", item
        if os.path.isdir(item):
            print "_dir:", item

  4. #4
    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
    Je n'utilise jamais walk et quelquefois glob. Je préfère utiliser os.listdir parce que je peux faire ce que je veux avec.

    Voilà un petit exemple de 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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import os
     
    ##############################################################################
    def contenurep(rep, nivmax=0, nivcour=1):
     
        # trouver le contenu du répertoire rep
        entrees = os.listdir(rep)
        entrees.sort(key=lambda v: v.upper()) # tri sans tenir compte de la casse
        sousrep = [] # recevra les noms des sous-répertoires
        sousfic = [] # recevra les noms des fichiers
        for entree in entrees:
            if os.path.isdir(os.path.join(rep, entree)):
                sousrep.append(entree)
            else:
                sousfic.append(entree)
        # affichage
        print
        print rep
        for srep in sousrep:
            print "[R]", srep
        for sfic in sousfic:
            print sfic
        # appel récursif si demandé        
        if nivmax==0 or nivcour<nivmax:
            for srep in sousrep:
                contenurep(os.path.join(rep, srep), nivmax, nivcour+1)
    Utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    rep = r"C:\Python27\Lib\ctypes"
    contenurep(rep, nivmax=1)
    Avec l'argument nivmax=1, seul le contenu du répertoire rep sera affiché:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    C:\Python27\Lib\ctypes
    [R] macholib
    [R] test
    util.py
    wintypes.py
    _endian.py
    _endian.pyc
    __init__.py
    __init__.pyc
    Avec l'argument nivmax=2, les 2 niveaux seront affichés:

    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
    C:\Python27\Lib\ctypes
    [R] macholib
    [R] test
    util.py
    wintypes.py
    _endian.py
    _endian.pyc
    __init__.py
    __init__.pyc
     
    C:\Python27\Lib\ctypes\macholib
    dyld.py
    dylib.py
    framework.py
    __init__.py
     
    C:\Python27\Lib\ctypes\test
    runtests.py
    test_anon.py
    test_arrays.py
    test_array_in_pointer.py
    test_as_parameter.py
    test_bitfields.py
    test_buffers.py
    test_byteswap.py
    test_callbacks.py
    test_cast.py
    test_cfuncs.py
    test_checkretval.py
    test_delattr.py
    test_errcheck.py
    test_errno.py
    test_find.py
    test_frombuffer.py
    test_funcptr.py
    test_functions.py
    test_incomplete.py
    test_init.py
    test_integers.py
    test_internals.py
    test_keeprefs.py
    test_libc.py
    test_loading.py
    test_macholib.py
    test_memfunctions.py
    test_numbers.py
    test_objects.py
    test_parameters.py
    test_pep3118.py
    test_pickling.py
    test_pointers.py
    test_prototypes.py
    test_python_api.py
    test_random_things.py
    test_refcounts.py
    test_repr.py
    test_returnfuncptrs.py
    test_simplesubclasses.py
    test_sizes.py
    test_slicing.py
    test_stringptr.py
    test_strings.py
    test_structures.py
    test_struct_fields.py
    test_unaligned_structures.py
    test_unicode.py
    test_values.py
    test_varsize_struct.py
    test_win32.py
    __init__.py
    Et avec nivmax=0 ou non cité dans l'appel, l'affichage traitera toute la profondeur de l'arbre.

  5. #5
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Bonsoir,
    Le dernier code est excellent !
    Je débute un peu en python et je souhaiterais copier par exemple tous les fichiers .txt listés précédemment dans les répertoire et sous-répertoires et les déplacer dans un autre répertoire (par exemple Copie) qui contiendra, lui, tous les fichiers txt.

    Je suis un peu perdu et je m'égare peut-être en voulant utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    shutil.copy('*.txt',"Copie/")
    Est-ce la bonne voie ?
    Faut-il le faire dans la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     for sfic in sousfic:
            print(sfic)
    ?
    A bientôt.

  6. #6
    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,

    @marco056

    C'est un problème différent sur plusieurs points:

    - ce n'est plus un listing, mais une copie: il faut donc passer un répertoire destination dans la fonction récursive. Attention: il ne faudra pas seulement copier les fichiers, mais aussi créer les sous-répertoires autant que nécessaire.

    - il y a un joker (="wildcard") comme "*.txt" qu'il faut tester avant de faire la copie, et qu'il faut donc passer dans la fonction récursive. Pour ce test, j'utilise la fonction fnmatch du module fnmatch

    - par ailleurs, tu parles de "déplacer" les fichiers, je suppose que c'est plutôt "copier". Sinon, il faudrait aussi supprimer les fichiers copiés de la source.

    - enfin, je ne sais pas si ta copie demande la notion de "niveaux" comme le code plus haut le demandait.

    Pour répondre à ta question sur shutil: shutil.copy demande pour sa source un nom de fichier sans joker et avec son chemin. Pour la destination, si c'est un répertoire, le fichier est recopié avec le même nom, sinon, il faut donner le nouveau nom du fichier avec son chemin. Mais je suis en train de reproduire le manuel...

    Si ça ne te suffit pas, précise ta demande. Si elle ne nécessite pas de "niveaux" (point important qui justifie ce fil), il faut créer une nouvelle question.

  7. #7
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Bonjour,

    Citation Envoyé par kiby56 Voir le message
    une idée ?
    Oui, c’est assez simple en fait.
    Pas besoin de récursivité ici (surtout que la récursivité est très mal géré en Python…).
    Pour lister un niveau il suffit de faire :
    Pour 2 niveaux :
    Pour 3 niveaux :
    Si on connais la profondeur, il suffit donc de générer la bonne chaîne et de faire un glob dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    from glob import glob
    from os.path import join
     
    def listdir_depth(directory='.', depth=1):
        return glob(join(directory, *(['*']*depth)))

  8. #8
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Merci tyrtamos, tu m'as donné une bonne piste avec fnmatch.

    Je mets mon code au as ou cela intéresserait quelqu'un ...
    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
     
    import os
    import os.path
    import shutil
    import fnmatch
     
    rep_source = ['/home/Musique/'] # Liste des répertoires source
    rep_exclus = [] # sous-répertoire à exclure
    rep_dest = '/home/Copie/' # Liste des répertoires destination
    type_fichier = ['*.mp3', '*.jpg'] # par exemple
     
    for repertoire in rep_source:
    	for root, repertoires, fichiers in os.walk(repertoire):
    		# Parcours récursif des répertoires
    		for dir in rep_exclus:
    			# On parcourt les répertoires exclus
    			if dir in dirs:
    				dirs.remove(dir)
    				# On enlève les répertoires exclus
    		if not os.path.exists(rep_dest):
    			os.makedirs(rep_dest)
    			# créé le répertoire destination si besoin
    		for chaque_type in type_fichier:
    			for fichier in fnmatch.filter(fichiers, chaque_type):
    				# filtre les fichiers à copier
    				print(fichier) # écrit les fichiers
    				shutil.copy2(os.path.join(root, fichier), rep_dest)
    				#copie les fichiers

Discussions similaires

  1. liste avec plusieurs niveaux hiérarchiques
    Par pigeon11 dans le forum ASP
    Réponses: 1
    Dernier message: 22/12/2008, 21h05
  2. Liste recursive de repertoire AVEC filtre
    Par skunkies dans le forum Langage
    Réponses: 3
    Dernier message: 24/11/2006, 08h59
  3. Listing d'un repertoire
    Par firejocker dans le forum MFC
    Réponses: 7
    Dernier message: 15/11/2005, 17h13
  4. Liste déroulante chainée : problème avec value
    Par jpascal dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 20/08/2005, 21h06
  5. Réponses: 2
    Dernier message: 08/07/2004, 01h04

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