[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. fichier = open(Filetxt, 'a') # à mettre en dehors de la boucle
    for path, dirs, files in os.walk(mydir):
        for filename in files:
            if filename.endswith('.txt'):
                search = os.path.join(path, filename)
                fichier.write(search+'\n')
    fichier.close()


    Non testé!!!
    -1
    1. Bonjour Fred.

      Et merci, ton code fonctionne bien avec les extensions.

      Mais si je cherche avec un mot, cela ne fonctionne pas.

      Je vais voir si je trouve rien de mon côté.

      @++
      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. Je n'ai toujours pas compris précisément ce que tu cherches à faire...
          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. 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. 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. 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. 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. Ça semble correct. Tu as un message d'erreur ?

                      Qu'y a-t-il comme résultat dans ton fichier ?
                      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. 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.

                            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. 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. Si tu as 27 fichiers avec le mot thomas inscris dedans, c'est ok, non?
                              0
                              1. 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. 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. 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. 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. mydir = r"{}".format(input("Entrer le répertoire: "))


                                      Tu entres ton répertoire sans guillemets!
                                      0
                                      • 1
                                      • 2