Lire et ecrire dans plusieurs sous-répertoires

David -  
Phil_1857 Messages postés 1872 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

A voir également:

10 réponses

Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

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
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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

Bonjour,

Alors, as-tu réussi ?

0

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

Posez votre question
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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

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
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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

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

et ça: 

fichier.append(svg) ?
0
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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

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
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

Bonjour,

alors as-tu testé ce dernier code ?

0