[Python] Lister un dossier avec récursivité

Résolu
Bonjour.

Etant sous windows, je m'étais initié à deux langages de programmation :
AutoIt et Batch.

Depuis peu (4 jours ^^), je découvre le Python : intéressant, et beaucoup plus rapide que le batch.

============

Je tente donc de lister un dossier.

J'arrive à lister un dossier sans récursivité
import os

mydir='c:\\users\\thomas\\desktop'
print("indiquer le dossier à lister (exemple : c:\python\)")
mydir = input("")
ch = mydir[-1:]
if not ch==('\\'):
mydir=mydir+'\\'

Filetxt="ListingDirSimple.txt"
fichier = open(Filetxt, "w")
entete = ['Listindir ~~ little boy62\n', # Notez l'utilisation des
'\n' # guillemets ou de l'apostrophe
'dossier de recherche : '+mydir,
'\n\n'
]
fichier.writelines(entete)
fichier.close()

files = os.listdir(mydir)
for file in files:
mysearch=mydir+file
fichier = open(Filetxt, "a")
fichier.write(mysearch+'\n')
fichier.close()

J'arrive à lister un dossier avec récursivité :
import os

print('indiquer le dossier à lister (exemple : c:\python\)')
mydir = input('')
ch = mydir[-1:]
if not ch==('\\'):
mydir=mydir+'\\'

Filetxt='ListingDirRec_1.txt'
fichier = open(Filetxt, 'w')
entete = ['Listindir ~~ little boy62\n', # Notez l'utilisation des
'\n' # guillemets ou de l'apostrophe
'dossier de recherche : '+mydir,
'\n\n'
]
fichier.writelines(entete)
fichier.close()

for path, dirs, files in os.walk(mydir):
for filename in files :
search=os.path.join(path, filename)
fichier = open(Filetxt, 'a')
fichier.writelines(search+'\n')
fichier.close()


Le problème : je n'arrive pas à lister récursivement un dossier en recherchant un fichier dont je connais un élément.

j'ai essayé ce code :
import os

mydir = 'c:\\users\\thomas\\desktop\\python\\*.*
# ch = mydir[-1:]
# if not ch==('\\'):
# mydir=mydir+'\\'

Filetxt='ListingDirRec_1.txt'
fichier = open(Filetxt, 'w')
entete = ['Listindir ~~ little boy62\n', # Notez l'utilisation des
'\n' # guillemets ou de l'apostrophe
'dossier de recherche : '+mydir,
'\n\n'
]
fichier.writelines(entete)
fichier.close()

for path, dirs, files in os.walk(mydir):
for filename in files :
search=os.path.join(path, filename)
fichier = open(Filetxt, 'a')
fichier.writelines(search+'\n')
fichier.close()

Cela ne fonctionne pas.

Comment faire pour lister récursivement un dossier, en recherchant un fichier présent, dont on connait un élément (*.txt par exemple) ?

Un gros débutant qui vous remercie de l'aide :D
++

22 réponses

Résumé de la discussion

Un débutant cherche à lister récursivement un dossier sous Windows en utilisant Python et à filtrer les fichiers par une partie du nom (par exemple .txt), mais rencontre des blocages. Plusieurs propositions utilisent os.walk pour parcourir les répertoires et filtrer les fichiers via filename.find('thomas') != -1, après conversion en minuscules. D'autres évoquent des approches basées sur endswith et startswith pour rechercher des suffixes ou préfixes, ou l'emploi du motif '*' pour exprimer des motifs, avec des détails sur la gestion des chemins. En complément, des échanges portent sur la casse, la normalisation des chemins et pourquoi certains scripts produisent des rapports incomplets, invitant à tester avec des exemples concrets.

Bobot (l’IA à votre service)
  1. Salut Fred.

    Oui, c'est résolu, grâce à toi. ;)

    Bonne soirée (journée).

    ++
    0
    1. Salut.

      Cela fonctionne impeccable.

      Ensuite, j'ai essayé de trouver comment faire un goto, ou un équivalent, et je suis tombé sur une de tes réponses.
      https://forums.commentcamarche.net/forum/affich-28883584-faire-une-boucle-sur-python-qui-relance-le-programme

      J'ai donc au final créer ce code :


      import os

      continuer = True
      while continuer:

      os.system("cls")
      print("Indiquez le dossier où débuter la recherche.\nPour information, le glissez/déposer peut fonctionner.")
      mydir = r"{}".format(input("\nEntrez le répertoire: "))
      os.system("cls")
      print("\nSi vous recherchez un fichier, dont vous connaissez le nom, ou une partie ?\nIndiquez-le.")
      print("\nUne recherche complète ?\nAppuyez sur Entrée sans rien indiquer.\n")
      mysearch = input("Nom (ou partie) du fichier: ")

      Filetxt = "c:\\users\\thomas\\desktop\\listingDir.txt"

      fichier = open(Filetxt, 'w')
      entete = ['Listindir ~~ little boy62\n\n', # Notez l'utilisation des
      'Dossier de recherche : '+mydir+'\n', # guillemets ou de l'apostrophe
      'Comportant cette chaine dans le nom du fichier : '+mysearch+'\n\n']
      fichier.writelines(entete)
      fichier.close()

      fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
      for path, dirs, files in os.walk(mydir):
      for filename in files:
      filename = filename.lower()
      if filename.find(mysearch) != -1:
      search = os.path.join(path, filename)
      fichier.write(search+'\n')
      fichier.close()
      os.system("cls")

      print("La recherche est terminée.\nVoulez vous revenir au programme ?\n1 : oui\n2 : non")
      choix = input("votre choix ? ")
      if choix not in ('1'):
      continuer = False

      Voilà, tout beau (je crois ^^) et fonctionnel.

      Merci beaucoup à toi, j'y serais jamais arrivé sans toutes ces aides que tu m'as apportées.

      @++
      0
      1. Résolu?
        0
    2. mydir = r"{}".format(input("Entrer le répertoire: "))


      Tu entres ton répertoire sans guillemets!
      0
      1. Salut.

        je vais encore t'embêter. (^^ )

        J'ai fait ce code :

        import os
        print('indiquer le dossier où débuter la recherche')
        mydir = input()

        Filetxt = "c:\\users\\thomas\\desktop\\listingDir.txt"

        fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
        for path, dirs, files in os.walk("r'"+mydir):
        for filename in files:
        filename = filename.lower()
        if filename.find("thomas") != -1:
        search = os.path.join(path, filename)
        fichier.write(search+'\n')
        fichier.close()

        Le fichier créé est vide xD

        Le problème vient de cette ligne je suppose : for path, dirs, files in os.walk("r'"+mydir):

        D'ailleurs, en faisant cela :
        import os
        print('indiquer le dossier où débuter la recherche')
        mydir = input("r'")

        Filetxt = "c:\\users\\thomas\\desktop\\listingDir.txt"

        fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
        for path, dirs, files in os.walk(mydir):
        for filename in files:
        filename = filename.lower()
        if filename.find("thomas") != -1:
        search = os.path.join(path, filename)
        fichier.write(search+'\n')
        fichier.close()

        Ca fonctionne, mais on voit : r'

        Où ai-je fauté encore ?

        @++ et merci.
        0
        1. Salut.

          Trop fort.

          Avec le dernier code, je trouve 30 fichiers, alors qu'avec un logiciel, j'en trouve 27.

          Décidément, le python trouve davantage en plus rapide. ;)

          J'aurai surement encore une question, mais là, je vais essayer de chercher par moi-même.

          Je te remercie pour toutes ces réponses.

          Je vais mettre ce topic en favoris, tous les codes vont me servir :)

          @+
          0
          1. Attention, thomas différent de Thomas, différent de thoMas, ... ce n'est pas sensible à la casse comme dans pratiquement tous langages de programmation d'ailleurs

            import os
            Filetxt = 'c:\\users\\thomas\\desktop\\listingDir.txt'
            mydir = r'c:\users\thomas\desktop'
            fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
            for path, dirs, files in os.walk(mydir):
                for filename in files:
                    filename = filename.lower()
                    if filename.find("thomas") != -1:
                        search = os.path.join(path, filename)
                        fichier.write(search+'\n')
            fichier.close()


            devrait le faire je pense...
            1
            1. Alors grand merci à toi...

              Je ne savais pas pour la casse.

              Par contre, j'ai fais de même en autoIt et en batch, sans avoir de faire ceci.

              Mais bon, le python me plait :=)

              Je teste ton code. Merci
              ++
              0
            2. Pourtant autoIt est aussi sensible à la casse ;)

              Bonne continuation...
              0
          2. Re ;)

            J'ai 27 fichiers ayant thomas inscrit dans le nom du fichier.

            Mais le script, dans le rapport créé, m'en affiche que 3.

            Et je ne sais pas pourquoi ^^

            ++
            0
            1. Si tu as 27 fichiers avec le mot thomas inscris dedans, c'est ok, non?
              0
              1. Salut.

                Et merci, c'était la bonne réponse :D

                Ce code fonctionne :

                import os
                Filetxt = 'c:\\users\\thomas\\desktop\\listingDir.txt'
                mydir = r'c:\users\thomas\desktop'
                fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
                for path, dirs, files in os.walk(mydir):
                for filename in files:
                if filename.find("thomas") != -1:
                search = os.path.join(path, filename)
                fichier.write(search+'\n')
                fichier.close()

                Par contre, je dois avoir 27 fichiers trouvés...

                J'en ai que 3.

                Mais bon, grâce à ton aide, on a bien avancé :)
                merci.

                @++ et bon appétit.
                0
                1. Salut.

                  En fait, rien ne s'affiche.

                  J'ai remplacé root par path, idem.

                  Je suis à la fois sous windows 7 / windows 8.
                  UAC désactivé, tout se lance avec les droits admin.

                  Je me demande si ce n'est pas à cause de mon architecture en 64bits.

                  Faut que je vois ca.

                  Je vais essayer de compacter ceci en exe. Et le lancer en tant qu'admin.
                  ++
                  0
                  1. Re ;)

                    J'ai remarqué une chose : la rapidité d'exécution du script.

                    Le script se lance et se termine en même pas 1 seconde... Je doute qu'il soit aussi rapide ^^

                    J'ai l'impression que la recherche ne se lance pas, et donc le rapport créé est vide.

                    @+
                    0
                  2. L'erreur est sans doute dans le format dont tu entres ton chemin mydir.

                    Essaies

                    r'C:\users\...\...

                    r' veut dire que tu prends la chaîne en brute entre les guillemets.
                    0
                2. Chez moi en tout cas je viens de tester, ça fonctionne très bien

                  import os
                  
                  for root, dirs, files in os.walk(mydir):
                      for filename in files:
                          if filename.find('thomas') != -1:
                              print(filename)


                  Tu verras si tes fichiers apparaissent à l'écran.
                  0
                  1. Salut.

                    Je n'ai pas d'erreur.

                    J'ai juste un fichier vide.

                    Et même si je met un autre terme, début ou fin du nom du fichier, c'est la même chose.

                    Faut que je teste ;)

                    @+
                    0
                    1. Ça semble correct. Tu as un message d'erreur ?

                      Qu'y a-t-il comme résultat dans ton fichier ?
                      0
                      1. Re ;)

                        Voici le code

                        import os
                        Filetxt = 'c:\\users\\thomas\\desktop\\listingDir.txt'
                        mydir = 'c:\\users\thomas\\desktop\\'
                        fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
                        for path, dirs, files in os.walk(mydir):
                        for filename in files:
                        if filename.find("thomas") != -1:
                        search = os.path.join(path, filename)
                        fichier.write(search+'\n')
                        fichier.close()

                        J'ai peut-être fauté quelque part, mais je ne vois pas où.

                        Si tu peux me mettre sur la voie, stp, ça serait sympa. ;)

                        Bonne soirée à toi.
                        Et merci encore.
                        0
                        1. Mais ça doit fonctionner, preuve à l'appui, le seul -1 est bien dans le cas où on ne trouve pas la sous chaine thomas.

                          >>> test = ["xxxthomasyyy.txt", "thomasxxxyyy.txt", "xxxyyy.txt"]
                          >>> for chaine in test:
                          ...     print(chaine.find('thomas'))
                          ... 
                          3
                          0
                          -1
                          


                          Je voudrais bien voir le code que tu as testé et que tu as ajouté au mien...
                          0
                          1. Salut.

                            Le dernier code ne fonctionne pas.

                            Si j'ai les 3 fichiers suivants :
                            xxxthomasyyy.txt
                            thomasxxxyyy.txt
                            xxxyyy.txt

                            Je veux que, quand je liste le dossier, je demande au script de recherche en précisant la chaine de caractère suivante : thomas.

                            Le code avec endswith fonctionne, ainsi qu'avec startswith.
                            Mais si la chaine de caractèré précisée ne se trouve ni au début, ni à la fin : ces fichiers sont ignorés.

                            Voici un code qui fonctionne :
                            import os
                            for path, dirs, files in os.walk("c:\\users\\thomas\\desktop\\"):
                            for filename in files :
                            print (os.path.join(path, filename))

                            Un code qui fonctionne, mais sans récursivité
                            import os

                            mydir='c:\\users\\thomas\\desktop'

                            Filetxt="ListingDirSimple.txt"
                            fichier = open(Filetxt, "w")
                            entete = ['Listindir ~~ little boy62\n', # Notez l'utilisation des
                            '\n' # guillemets ou de l'apostrophe
                            'dossier de recherche : '+mydir,
                            '\n\n'
                            ]
                            fichier.writelines(entete)
                            fichier.close()

                            files = os.listdir(mydir)
                            for file in files:
                            mysearch=mydir+file
                            fichier = open(Filetxt, "a")
                            fichier.write(mysearch+'\n')

                            Merci encore de ton aide.

                            @++
                            0
                            1. fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
                              for path, dirs, files in os.walk(mydir):
                                  for filename in files:
                                      if filename.find("motachercher") != -1:
                                          search = os.path.join(path, filename)
                                          fichier.write(search+'\n')
                              fichier.close()


                              ?

                              Ça recherche dans le nom du fichier une sous chaine, c'est ça que tu veux?

                              Sinon donne un exemple qui fonctionne et un qui ne doit pas fonctionner.
                              0
                              1. En fait :

                                ~~ avec endswith : cela permet de faire une recherche récursive d'un fichier dont on connait la fin du nom.
                                ~~ avec startswith : cela permet de faire une recherche récursive d'un fichier dont on connait le début du nom.

                                Mon problème :
                                C'est que je peux connaitre un morceau du nom de fichier mais je ne connais pas sa position.

                                C'est pour cela que j'ai utilisé les astérisques ( * ).
                                Dans ce style :
                                mydir = 'c:\\users\\thomas\\desktop\\python\\*.*
                                .
                                ou :
                                mydir = 'c:\\users\\thomas\\desktop\\python\\*


                                Donc je continue mes recherches ;)

                                @+ et merci à toi.
                                0
                                1. Je n'ai toujours pas compris précisément ce que tu cherches à faire...
                                  0
                                  1. Re ;)

                                    https://docs.python.org/release/2.5.2/lib/string-methods.html

                                    Je vois donc endswith et startswith.

                                    Cela fonctionne bien.

                                    Mais si l'élément ne se trouve, ni à l'extrême gauche, ni à l'extrême droite : faut que je trouve un moyen pour me faire comprendre ^^

                                    En tout cas, merci de ta réponse, cela va m'aider pour d'autres scripts.

                                    Bon, c'est pas tout, faut que j'aille faire des recherches.

                                    ++
                                    0
                                    • 1
                                    • 2