Lire et ecrire dans plusieurs sous-répertoires

David -  
Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   -

Bonjour,

but de mon programme: lire et écrire, chaque fichiers (.svg) de tous mes sous-répertoires
Pour instant je n'arrive qu'à écrire dans le fichier de mon dernier sous-repertoire
car la fonction os.listdir(join(mypath,f)) ne prends en compte que les fichiers d'un seul sous-répertoire et pas les fichiers de tous les sous-répertoires comme je le souhaite, la méthode par liste avec append doit être utiliser.
batch2 est le répertoire et batch2-1, batch2-2, batch2-3 sont les sous-répertoires

import os

from os import listdir            #utlisé pour lister tout dans un répertoire et fichiers
from os.path import isfile, join  #utilisé pour lister des fichiers
mypath = "C:\\Users\\David.dupont\\Documents\\test\\batch2"

fichier =[]
for f in listdir(mypath):
    fichier.append(join(mypath,f))
    print(join(mypath,f))

list_SVG=join(mypath,f)#list des chemins des .svg
search_text="--uatb2b--c.visual"
replace_text=".lightning."
  # liste des chemins vers les.svg
app=r"C:\Program Files (x86)\Notepad++.exe"
cmd="Notepad %s"%list_SVG

for filename in os.listdir(list_SVG):  #retourne une liste contenue dans un seul répertoire, le dernier si plusieurs
    with open(os.path.join(list_SVG, filename),'r') as file:
        data = file.read()
        data = data.replace(search_text, replace_text)
    with open(os.path.join(list_SVG, filename),'w') as file:
        file.write(data)

print(list_SVG)
print("Text replaced")


Windows / Chrome 105.0.0.0

10 réponses

  1. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    Bonjour,

    Dans ta liste fichier, on doit normalement obtenir ceci:

    ['batch2-1', 'batch2-2', 'batch2-3']

    Ensuite, tu peux boucler sur cette liste et faire à nouveau pour chaque élément:

    for f in listdir(element):
        ...

    pour avoir le contenu de chacun des 3 sous-répertoires

    0
  2. David
     

    Merci Phil

    Mais la c'est un test pour 3 sous-répertoires, avant de passer à celui composé de plusieurs centaines de sous-répertoires, je voudrai une fonction qui prenne en compte chacun de mes sous-répertoires sans les nommer.

    0
  3. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    OK,

    Alors tu pourrais écrire une fonction récursive:

    liste_files(rep):
    
        pour chaque élément du répertoire:
    
            si répertoire:
    
                liste_files(nom_du rep)
    
            sinon:
    
                fichier : on le traite avec une fonction

    appelée avec

    liste_files(mypath)
    0
    1. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
       

      En gros, ça donnerait ça:

      def list_files(path):
          ''' Exploration d'une arborescence de répertoires '''
      
          for name in os.listdir(path):
              full_name = path+'\\'+name
      
              if(os.path.isdir(full_name)): #C'est un répertoire: on l'explore
                  list_files(full_name)
              else:
                  if('.svg' in full_name): update_file(full_name) #C'est un fichier : on le traite
      
      list_files(my_path)
      
      0
  4. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    Bonjour,

    Alors, as-tu réussi ?

    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. David
     

    Bonjour

    Je ne suis pas très familier avec les fonctions récursives, je n'ai que 3 mois de python.
    j'ai un message erreur, on essai d'aller au bout de ta proposition. si tu pouvais me dire quelle est erreur.


    import os

    from os import listdir            #utlisé pour lister tout dans un répertoire et fichiers
    from os.path import isfile, join  #utilisé pour lister des fichiers
    path = "C:\\Users\\David.dupont\\Documents\\test\\batch2"
    update_file=[]

    def list_files(path):
        ''' Exploration d'une arborescence de répertoires '''

        for name in os.listdir(path):
            full_name= path+'\\'+name

            if(os.path.isdir(full_name)): #C'est un répertoire: on l'explore
                list_files(full_name)
            else:
                if('.svg' in full_name): update_file(full_name) #C'est un fichier : on le traite

    list_files(path)
    résultat
    Traceback (most recent call last):
      File "C:\Users\\David.dupont\PycharmProjects\pythonProject5\svgconvertest3.py", line 19, in <module>
        list_files(path)
      File "C:\Users\\David.dupont\PycharmProjects\pythonProject5\svgconvertest3.py", line 15, in list_files
        list_files(full_name)
      File "C:\Users\\David.dupont\PycharmProjects\pythonProject5\svgconvertest3.py", line 17, in list_files
        if('.svg' in full_name): update_file(full_name) #C'est un fichier : on le traite
    TypeError: 'list' object is not callable

    Sinon je souhaiterai utiliser cette proposition si tu la connais 


    for f in listdir(mypath):
        print(listdir(join(mypath,f)) #liste des fichier dans ss-repertoires
    résultat:
    ['CT3-69TV-Stage5-Cover-Vector1350_B.svg']
    ['CT3-69TV-Stage5-Crankcase-Supra_A.svg']
    ['CT3-69TV-SHE1113-PistonAndCrankshaft.svg', 'CT3-69TV-SHE1113-SpeedControlPlate.svg', 'CT3-69TV-Stage5-Crankcase-Vector1350_A.svg']
    je souhaiterai regrouper ces différents fichier dans une liste puis avec la fonction append j'effectue les changements un par un de mes fichiers.svg

    0
  7. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    Bonjour,

    if('.svg' in full_name): update_file(full_name) #C'est un fichier : on le traite

    Bien évidemment, update_file est une fonction, pas une liste comme tu le fais ici:

    update_file=[]

    Et dans cette fonction, on met à jour le fichier comme tu le fais dans ton code initial:

    def update_file(file_name):
        ''' mise à jour du fichier'''
    
        #ton code où tu lis le fichier, remplace le texte, et ré écris ça dedans
    
        print('Fichier {} mis à jour'.format(file_name))
    

    Pas besoin de liste, on met à jour au fur et à mesure, le code est simple:

    def update_file(file_name):
        ''' mise à jour du fichier'''
    
        with open(file_name,'r') as file:
            data = file.read()
            data = data.replace(search_text, replace_text)
    
        with (openfile_name,'w') as file: file.write(data)
    
        print('Fichier {} mis à jour'.format(file_name))
    
    def list_files(path):
        ''' Exploration d'une arborescence de répertoires '''
    
        for name in os.listdir(path):
            full_name = path+'\\'+name
    
            if(os.path.isdir(full_name)): #C'est un répertoire: on l'explore
                list_files(full_name)
            else:
                if('.svg' in full_name): update_file(full_name) #C'est un fichier : on le traite
    
    search_text="--uatb2b--c.visual"
    replace_text=".lightning."
    
    path = "C:\\Users\\David.dupont\\Documents\\test\\batch2"
    list_files(path)
    0
  8. David
     

    j'ai trouvé
     

    import os
    
    from os import listdir            #utlisé pour lister tout dans un répertoire et fichiers
    from os.path import isfile, join  #utilisé pour lister des fichiers
    
    mypath = "C:\\Users\\david.dupont\\\Documents\\test\\batch2"
    svg=[]
    fichier=[]
    list_svg = [os.path.join(r,file) for r,d,f in os.walk(mypath) for file in f]
    print(list_svg)
    
    app=r"C:\Program Files (x86)\Notepad++.exe"
    cmd="Notepad %s"%svg
    
    for svg in list_svg:
        fichier.append(svg)
        with open(os.path.join(svg, svg),'r') as file:
            data = file.read()
            data = data.replace("--uatb2b--c.visual", ".lightning.")
        with open(os.path.join(svg, svg),'w') as file:
            file.write(data)
        
    
    print("text replaced")
    0
  9. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    OK, et ça sert à quoi ces 2 lignes avec Notepad ?

    et ça: 

    fichier.append(svg) ?
    0
  10. David
     

    le format .svg est une image pour modifier le texte je ne peux le faire qu'avec notepad

    finalement cette fonction n'est pas nécessaire "fichier.append(svg)"

    je voulais dire pour chaque .svg de ma list_svg ont applique les fonctions décrites aux lignes 18 à 22

    finalement ca devient

    for svg in list_svg:
        with open(os.path.join(svg, svg),'r') as file:
            data = file.read()
            data = data.replace("--uatb2b--c.visual", ".lightning.")
        with open(os.path.join(svg, svg),'w') as file:
            file.write(data)
    0
  11. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    Le format .svg est une image pour modifier le texte je ne peux le faire qu'avec notepad

    Ok, mais tu défini 2 variables : app et cmd, mais tu ne t'en sert pas, tu ne lances pas Notepad

    Refait un test sans ces 2 lignes pour voir (ton code sans les lignes inutiles : )

    import os
    from os import listdir            #utlisé pour lister tout dans un répertoire et fichiers
    from os.path import isfile, join  #utilisé pour lister des fichiers
    
    mypath = "C:\\Users\\david.dupont\\\Documents\\test\\batch2"
    list_svg = [os.path.join(r,file) for r,d,f in os.walk(mypath) for file in f]
    print(list_svg)
    
    for svg in list_svg:
        with open(os.path.join(svg, svg),'r') as file:
            data = file.read()
            data = data.replace("--uatb2b--c.visual", ".lightning.")
        with open(os.path.join(svg, svg),'w') as file:
            file.write(data)
    
    print("text replaced")
    0
    1. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
       

      Bonjour,

      alors as-tu testé ce dernier code ?

      0