Explorateur de fichier

Fabien -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,

J'ai écrit un programme, mais quand j'ai deux fois le même nom, il me fait :
test.txt
en
test_1.txt
, et ensuite il fait
test_1_2.txt
au lieu de passer directement à
test_2.txt
.

Si vous pouviez m'aider, ce serait vraiment gentil de votre part. Je dois le rendre demain matin.

    def renommer_fichier_2(self):
        self.nom = self.fenetre_renommer_entree.get()
        self.fichier_nouveau_nom = os.path.join(os.path.dirname(self.fichier_a_renommer), self.fenetre_renommer_entree.get()+os.path.splitext(self.fichier_a_renommer)[1])
        print(os.path.dirname(self.fichier_a_renommer))
        print(os.path.splitext(self.fichier_a_renommer))
        print(self.fichier_nouveau_nom)
        self.fenetre_renommer.destroy()
        self.nombre = 1
        try:
            os.rename(self.fichier_a_renommer, self.fichier_nouveau_nom)
            tmg.showinfo(title="Fichier renommé",message="Votre fichier a été renommé")
            
        except FileExistsError:
            while True:
                try:
                    os.rename(self.fichier_a_renommer, os.path.join(os.path.dirname(self.fichier_a_renommer),self.nom+'_'+str(self.nombre)+os.path.splitext(self.fichier_a_renommer)[1]))
                    tmg.showinfo(title="Fichier renommé",message="Votre fichier a été renommé")
                    break
                except FileExistsError:
                   self.nombre +=1

3 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Bonjour,

    Si j'ai bien compris ce que tu veux faire, j'utiliserais une expression régulière dont le but serait d'extraire (si on considère que le fichier s'appelle
    fichier_11.txt
    ):
    • tout ce qui est avant l'index (
      prefix
      ), e.g.,
      fichier_
      ;
    • l'index (
      index
      ), e.g.,
      11
      ;
    • tout ce qui est après l'index (
      suffix
      ), e.g.,
      .txt
      .


    import re
    
    RE_INDEXED_FILENAME = re.compile(r"(.*)(\d)([.].*)")
    
    def increment_filename(filename):
        m = RE_INDEXED_FILENAME.match(filename)
        if not m: 
            raise RuntimeError(f"Invalid filename: {filename}")
        (prefix, index, suffix) = (m.group(i) for i in range(1, 4))
        index = int(index)
        return f"{prefix}{index + 1}{suffix}"
    
    filename = "fichier_11.txt"
    print(increment_filename(filename)) # Affiche fichier_12.txt


    Est-ce que ça te convient ?

    Bonne chance
    1
    1. Fabien
       
      Merci de ta réponse rapide,
      Comment pourrais-je l'intégrer dans mon script initiale?
      0
    2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944 > Fabien
       
      Si je reprends tes notations, je dirais tout simplement :
          def renommer_fichier_2(self):
              fichier_a_renommer = self.fichier_nouveau_nom
              fichier_nouveau_nom = increment_filename(fichier_a_renommer)
              os.rename(fichier_a_renommer, fichier_nouveau_nom)

      Je ne comprends pas trop pourquoi dans ton script tu mémorises ces variables dans
      self
      donc c'est pour ça qu'ici j'ai enlevé le
      self.
      qui les précédaient.

      Bonne chance
      1
    3. Fabien > mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Comme cela?
      Il me donne des erreurs.

          
         def increment_filename(self):
              RE_INDEXED_FILENAME = re.compile(r"(.*)(\d)([.].*)")
              m = RE_INDEXED_FILENAME.match(filename)
              if not m: 
                  raise RuntimeError(f"Invalid filename: {filename}")
              (prefix, index, suffix) = (m.group(i) for i in range(1, 4))
              index = int(index)
              return f"{prefix}{index + 1}{suffix}"
      
      
          def renommer_fichier_2(self):
              fichier_nouveau_nom = self.increment_filename(fichier_a_renommer)
              fichier_a_renommer = self.fichier_nouveau_nom
              os.rename(fichier_a_renommer, fichier_nouveau_nom)
      


      Merci
      0
    4. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944 > Fabien
       
      Pourquoi veux tu faire de
      increment_filename
      une méthode de classe ? Elle peut rester une fonction en dehors de ta classe. Du coup l'appel ce ferait comme je t'ai indiqué. Si tu as des erreurs, il faut me les reporter (ainsi que la section de code concernée)...
      0
    5. Fabien > mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention  
       
      J'obtiens ceci comme erreur :

      Exception in Tkinter callback
      Traceback (most recent call last):
        File "C:\Users\fabien-c\AppData\Local\Programs\Spyder\pkgs\tkinter\__init__.py", line 1705, in __call__
          return self.func(*args)
        File "C:\Users\ali-c\Desktop\OS_Script\operations_os.py", line 49, in renommer_fichier_2
          fichier_nouveau_nom = self.increment_filename(fichier_a_renommer)
      UnboundLocalError: local variable 'fichier_a_renommer' referenced before assignment
      

      Et le code concerné :
      fichier_nouveau_nom = self.increment_filename(fichier_a_renommer)
      


      Et le code complet que j'ai :
      from tkinter import *
      from tkinter import filedialog as tfd
      from tkinter import messagebox as tmg
      import os
      import shutil
      import re
      
      class OS(object):
          def __init__(self):
              self.fenetre_principale = Tk()
              self.fenetre_principale.title("Gestionnaire de fichiers et dossiers")
              self.titre = Label(self.fenetre_principale, text = "Gestionnaire de fichiers",bg="grey",padx = 5, pady = 5, font=("Courier", 15, "italic"))
              self.titre.pack()
              self.fenetre_principale.geometry("300x200")
              self.fenetre_principale.config(bg="grey", padx = 5, pady = 5)
              self.fenetre_principale.resizable(0,0)
              
              self.bouton_renommer_fichier = Button(self.fenetre_principale,text="Renommer un fichier", width=20, command=self.renommer_fichier, bg="grey", padx = 5, pady = 5, font=("Arial", 10)).pack(side=TOP)
              
          def renommer_fichier(self):
              self.fichier_a_renommer = tfd.askopenfilename(title="Choisissez un fichier à renommer",filetypes=[("Tous les fichiers","*.*")])
              self.fenetre_renommer = Toplevel(self.fenetre_principale)
              self.fenetre_renommer.title("Renommer le fichier")
              self.fenetre_renommer.config(bg="grey", padx = 5, pady = 5)
              self.fenetre_renommer.geometry("250x100")
              self.fenetre_renommer.resizable(0,0)
              self.fenetre_renommer_texte = Label(self.fenetre_renommer,text="Ecrivez le nouveau nom du fichier", font=("Arial", 10), bg="grey")
              self.fenetre_renommer_texte.pack(side=TOP)
              self.fenetre_renommer_entree = Entry(self.fenetre_renommer,width=80)
              self.fenetre_renommer_entree.pack(side=TOP)
              self.fenetre_renommer_bouton = Button(self.fenetre_renommer,text="OK",command=self.renommer_fichier_2, font=("Arial", 10), bg="grey")
              self.fenetre_renommer_bouton.pack(side=TOP)
      
          def increment_filename(filename):
              RE_INDEXED_FILENAME = re.compile(r"(.*)(\d)([.].*)")
              m = RE_INDEXED_FILENAME.match(filename)
              if not m: 
                  raise RuntimeError(f"Invalid filename: {filename}")
              (prefix, index, suffix) = (m.group(i) for i in range(1, 4))
              index = int(index)
              return f"{prefix}{index + 1}{suffix}"
      
          def renommer_fichier_2(self):
              fichier_nouveau_nom = self.increment_filename(fichier_a_renommer)
              fichier_a_renommer = self.fichier_nouveau_nom
              os.rename(fichier_a_renommer, fichier_nouveau_nom)
                          
      if __name__ == '__main__':
          edf=OS()
          edf.fenetre_principale.mainloop()
      0
  2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Bonjour,

    Personnellement, je n'ai pas compris ta question. Quels sont ces noms de fichiers dont tu parles ? Le code est incomplet et tu ne nous dit pas ce que tu veux faire. Essaye d'avoir un code minimal qui met en évidence ton problème et essaye d'expliquer clairement ce que tu veux faire (paramètres d'entrées, résultat attendu), sans quoi on peut difficilement t'aider...

    J'ai l'impression que ton problème concerne les lignes 9 à 20. Indique les fichiers qui existe. Indique les renommages que tu tentes de déclencher et comment (en particulier, si le fichier cible existe) ils doivent être faits.

    Bonne chance
    0
  3. Fabien
     
    Bonjour,
    Désolé de cette réponse tardive.

    --------------------------------------------------------------------
    from tkinter import *
    from tkinter import filedialog
    import os
    print("Liste des fichiers présents dans le dossier : ",os.listdir())
    # ['aa.txt', 'bb.txt', 'operations_os_test.py']
    
    def renommer_fichier():
        global fichier_a_renommer
        fichier_a_renommer = filedialog.askopenfilename(title="Choisissez un fichier à renommer",filetypes=[("Tous les fichiers",".")])
        print("Chemin complet du fichier : ",fichier_a_renommer)
        print("Chemin complet du dossier parent du fichier : ",os.path.dirname(fichier_a_renommer))
        print("Tuple dossier parent et fichier + extension : ",os.path.split(fichier_a_renommer))
        print("Tuple fichier et extension : ",os.path.splitext(fichier_a_renommer))
        print("Extension : ",os.path.splitext(fichier_a_renommer)[1])
        """
        Chemin complet du fichier :  C:/Users/fabrice/Desktop/dossier_test/bb.txt
        Chemin complet du dossier parent du fichier :  C:/Users/fabrice/Desktop/dossier_test
        Tuple fichier et extension :  ('C:/Users/fabrice/Desktop/dossier_test/bb', '.txt')
        Extension :  .txt
        """
    def renommer_fichier_2():
        renommer_fichier()
        nouveau_nom = input("Le nouveau nom que vous avez choisi : ")
    
        try:
            fichier_nouveau_nom = os.path.join(os.path.dirname(fichier_a_renommer), nouveau_nom+os.path.splitext(fichier_a_renommer)[1])
            os.rename(fichier_a_renommer, fichier_nouveau_nom)
        except FileExistsError:
            iteration = 1
            while True:
                if nouveau_nom+"()"+str(iteration)+os.path.splitext(fichier_a_renommer)[1] in os.listdir():
                    iteration = iteration+1
                else:
                    break
            fichier_nouveau_nom = os.path.join(os.path.dirname(fichier_a_renommer), nouveaunom+""+str(iteration)+os.path.splitext(fichier_a_renommer)[1])
            os.rename(fichier_a_renommer, fichier_nouveau_nom)
    
    renommer_fichier_2()
    

    --------------------------------------------------------------

    Voici donc le script en question, et le soucis c'est que j'aimerais diviser le nom du fichier en trois parties c'est a dire : imaginons j'ai "Test_1.txt" j'aimerais le diviser en trois parties qui donnera "Test", "1", ".txt" pour que quand je modifie deux fois le même fichier qu'il me fasse "Test_2.txt".

    Et dans mon script actuel quand j'ai une fois "Test_1.txt" et que je veux modifier le deuxième avec le même nom que le premier, il me fait "Test_1_1.txt" au lieu de "Test_2.txt".
    0