Lire et ecrire dans plusieurs sous-répertoires

Fermé
David - 30 sept. 2022 à 13:58
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 - 4 oct. 2022 à 11:16

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 30 sept. 2022 à 15:10

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

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 30 sept. 2022 à 15:53

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 1 oct. 2022 à 11:12

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
2 oct. 2022 à 11:18

Bonjour,

Alors, as-tu réussi ?

0

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

Posez votre question

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 2 oct. 2022 à 16:49

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

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 2 oct. 2022 à 18:36

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

et ça: 

fichier.append(svg) ?
0

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 2 oct. 2022 à 19:18

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
4 oct. 2022 à 11:16

Bonjour,

alors as-tu testé ce dernier code ?

0