Page 1 sur 2

Changer les noms de fichiers avec accents

Publié : dim. 03/mai/2020 18:13
par Jacobus
Une petite routine pour remplacer les caractères accentués par des caractères sans accent dans les noms des fichiers et dossiers.
Les fichiers et dossiers sont renommés (de façon récursive) avec des noms sans accents ni apostrophes.
procédure que j'ai dû faire pour utiliser les fonctions packer/zip qui créént des fichiers compressés aux noms bizarres si des accents s'y trouvent.
Et je n'ai pas trouvé de fonction interne pour y remédier.
Cela reste assez rapide, mais si vous avez une meilleure solution, n'hésitez pas
-> Si pour tester vous ne voulez pas renommer vos fichiers, commentez la fonction RenameFile()

Code : Tout sélectionner

Procedure.s ChangeFileNameToZip(FileNameToZip$)
 ; àçéèêëîïôöùüÂÇÉÈÊËÎÏÔÖÙÜ
  ChangeFileName$ = ReplaceString(FileNameToZip$, "à", "a", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ç", "c", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "é", "e", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "è", "e", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ê", "e", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ë", "e", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "î", "i", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ï", "i", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ô", "o", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ö", "o", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ù", "u", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "ü", "u", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Â", "A", #PB_String_CaseSensitive, 1) 
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ã", "A", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ç", "C", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "É", "E", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "È", "E", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ê", "E", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ë", "E", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Î", "I", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ï", "I", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ô", "O", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ö", "O", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ù", "U", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "Ü", "U", #PB_String_CaseSensitive, 1)
  ChangeFileName$ = ReplaceString(ChangeFileName$, "'", " ", #PB_String_CaseSensitive, 1)
  ProcedureReturn ChangeFileName$
  
EndProcedure

Procedure.s Directory_ChangeFileName(MyDir.s, IDdir.l=0)
  If Right(MyDir, 1) <> "\"
    MyDir + "\"
  EndIf  
  If ExamineDirectory(IDdir, MyDir, "*.*") 
    While NextDirectoryEntry(IDdir)   
      If DirectoryEntryName(IDdir) <> "." And DirectoryEntryName(IDdir) <> ".."
        MyFile.s = MyDir + DirectoryEntryName(IDdir) 
         Debug "Fichier initial : "+MyFile             
        MyNewFile.s = ChangeFileNameToZip(MyFile.s) 
        Debug "Nom Fichier modifié : "+MyNewFile  
        If RenameFile(MyFile.s, MyNewFile.s)<>0
        Debug "Fichier renommé : "+MyNewFile
        Debug "---"
        EndIf 
          ; rappel de la procédure à chaque dossier rencontré
        If DirectoryEntryType(IDdir) = #PB_DirectoryEntry_Directory         
          Directory_ChangeFileName(MyDir + DirectoryEntryName(IDdir), IDdir + 1)       
        EndIf        
      EndIf
    Wend    
    FinishDirectory(IDdir)    
  EndIf 
EndProcedure

;-Test
Direct.s = PathRequester("Choisissez un répertoire", "")
If Direct 
  Directory_ChangeFileName(Direct) 
EndIf

Re: Changer les noms de fichiers avec accents

Publié : lun. 04/mai/2020 15:06
par TazNormand
Je me suis permis une modif en mode récursif :

Code : Tout sélectionner

Global idx.i=0, char2replace.s="àaçcéeèeêeëeîiïiôoöoùuûuüuÂAÃAÇCÈEÊEËEÎIÏIÔOÖOÙUÜU' "

Procedure.s replaceAccents(fileName$,index)
  returnFileName$=ReplaceString(fileName$,Mid(char2replace,index,1),Mid(char2replace,index+1,1),#PB_String_CaseSensitive,1)
  If index<Len(char2replace)
    index=index+2
    ProcedureReturn replaceAccents(returnFileName$,index)
  Else
    ProcedureReturn returnFileName$    
  EndIf  
EndProcedure

Procedure.s Directory_ChangeFileName(MyDir.s, IDdir.l=0)
  If Right(MyDir, 1) <> "\"
    MyDir + "\"
  EndIf 
  If ExamineDirectory(IDdir, MyDir, "*.*")
    While NextDirectoryEntry(IDdir)   
      If DirectoryEntryName(IDdir) <> "." And DirectoryEntryName(IDdir) <> ".."
        MyFile.s = MyDir + DirectoryEntryName(IDdir)
        Debug "Fichier initial : "+MyFile                     
        MyNewFile.s = replaceAccents(MyFile.s,1)        
        Debug "Nom Fichier modifié : "+MyNewFile 
        ;If RenameFile(MyFile.s, MyNewFile.s)<>0
        Debug "Fichier renommé : "+MyNewFile
        Debug "---"
        ;EndIf
          ; rappel de la procédure à chaque dossier rencontré
        If DirectoryEntryType(IDdir) = #PB_DirectoryEntry_Directory         
          Directory_ChangeFileName(MyDir + DirectoryEntryName(IDdir), IDdir + 1)       
        EndIf       
      EndIf
    Wend   
    FinishDirectory(IDdir)   
  EndIf
EndProcedure

;-Test
Direct.s = PathRequester("Choisissez un répertoire", "")
If Direct
  Directory_ChangeFileName(Direct)
EndIf

Re: Changer les noms de fichiers avec accents

Publié : lun. 04/mai/2020 15:30
par SPH
Merci a vous 2 8)

TazNormand : la récursivité, c'est "inclure tous les repertoires; quelque soit leur nombres" ?
C'est réglable ? (genre : s'enfoncer de 3 dossiers max)

Je pose la question, je n'ai jamais fait, c'est pour ca... :oops: :|

Re: Changer les noms de fichiers avec accents

Publié : lun. 04/mai/2020 16:22
par TazNormand
la récursivité que j'ai appliquée c'est pour l'appel de la fonction par elle-même (replaceAccents()) :

Code : Tout sélectionner

ProcedureReturn replaceAccents(returnFileName$,index)
De son côté, Jacobus a appliqué la récursivité avec cette partie du code dans la procédure Directory_ChangeFileName(MyDir.s, IDdir.l=0)

Code : Tout sélectionner

        If DirectoryEntryType(IDdir) = #PB_DirectoryEntry_Directory         
          Directory_ChangeFileName(MyDir + DirectoryEntryName(IDdir), IDdir + 1)       
        EndIf 

Re: Changer les noms de fichiers avec accents

Publié : lun. 04/mai/2020 17:35
par GallyHC
Bonjour,

Une autre méthode simple (le récursif a tendance a prendre de la mémoire, même si la c'est négligeable).

Code : Tout sélectionner

Procedure.s replaceAccents(value.s)
  
  Define.l i
  Define.s nonValid = "àáâãäåçèéêëìíîïðòóôõöùúûüýÿ'"
  Define.s carValid = "aaaaaaceeeeiiiioooooouuuuyy "
  For i=0 To Len(nonValid)
    value = ReplaceString(value, Mid(nonValid, i, 1), Mid(carValid, i, 1))
  Next i  
  ProcedureReturn value
  
EndProcedure

Debug replaceAccents("Ceci est un test avec une chaîne de caractères et aussi àáâãäåçèéêëìíîïðòóôõöùúûüýÿ")
Cordialement,
GallyHC

Re: Changer les noms de fichiers avec accents

Publié : lun. 04/mai/2020 19:15
par Jacobus
:) Merci à vous pour cette amélioration beaucoup moins lourde. Vos deux solutions sont très bien.
Cette astuce/fonction sera très utile dans le traitement des fichiers avec la lib Packer() qui merdoie surtout lors de la décompression des fichiers aux noms accentués.
Si on voulait faire l'inverse, ré accentuer les noms de fichiers lors de la décompression la difficulté serait de déterminer le type d'accent, ne serais-ce que pour la lettre "e", quel accent remettre.
La solution serait alors de stocker les noms dans un fichier pour les réutiliser par la suite. Mais est-ce que cela en vaudrait la peine ? Je n'en suis pas sûr, à moins d'être Norvégien...

Re: Changer les noms de fichiers avec accents

Publié : lun. 04/mai/2020 19:29
par Jacobus
SPH a écrit :TazNormand : la récursivité, c'est "inclure tous les repertoires; quelque soit leur nombres" ?
C'est réglable ? (genre : s'enfoncer de 3 dossiers max)|
En fait la récursivité, en l'espèce, c'est le fait qu'un programme (ici la procédure) se rappelle lui même. Comme te l'a fait remarquer TazNormand dans mon exemple la procédure est relancée dans la procédure. Ici il s'agit d'examiner un répertoire de la même manière à chaque fois pour traiter tous les sous-répertoires. Mais tu peux faire bien d'autres choses, même des boucles infinies, mais ça il vaut mieux éviter.
Pour régler le niveau de récursivité, je pense qu'en ajoutant un compteur, +1 à chaque fois que tu rencontres un dossier, tu peux indiquer qu'à 3 il faut arrêter par exemple ou sortir de la boucle.

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 7:36
par Marc56
procédure que j'ai dû faire pour utiliser les fonctions packer/zip qui créént des fichiers compressés aux noms bizarres si des accents s'y trouvent.
Quelle version de PB ?
Par curiosité, j'ai testé la compression de fichier avec PB, UseZipPacker() et des accents (dans les noms de fichiers et dans celui de l'archive), ça fonctionne sans problèmes sous Windows 10 x64 PB 5.72 LTS (pas testé avec d'autres versions ni OS)

:wink:

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 8:59
par Jacobus
@Marc56, la même que toi. Format de fichier UTF8.

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 9:45
par Marc56
Voila une bafouille moche que j'ai créé pour tester l'archivage avec des noms de fichiers tordus (mais néanmoins valides pour Windows)
Ça fonctionne pour compacter (je n'ai pas testé dans l'autre sens avec les fonctions PB)
(Oui, la partie pour exclure les 9 caractères interdits pourrait être améliorée)

Code : Tout sélectionner

SetCurrentDirectory(GetTemporaryDirectory())

; Créons un nom de fichier bien tordu :o)
Repeat
    i + 1
    Char = Random(255, 32)
    Select Char
        Case 32, 33, 35 To 41, 43 To 46, 48 To 57, 59, 61, 63 To 91, 93 To 124, 125 To 255
            F_Name$+ Chr(Char)
    EndSelect
Until i >= 10
; Caractères interdits
; https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
; The following reserved characters:
;     < (less than)             60
;     > (greater than)          62
;     : (colon)                 58
;     " (double quote)          34
;     / (forward slash)         47
;     \ (backslash)             92
;     | (vertical bar Or pipe)  124
;     ? (question mark)         63
;     * (asterisk)              42

F_Name$ = Left(F_Name$, 10)
Debug "Chaine : " + F_Name$

; Remplissons ce fichier avec n'importe quoi
F_Name$ + ".txt"
Debug "Fichier: " + F_Name$
If OpenFile(0, F_Name$)
    For i = 1 To 10000
        WriteString(0, F_Name$)
    Next
    CloseFile(0)
Else
    Debug "Ne peux écrire dans: " + F_Name$
    End
EndIf

; Archivons
UseZipPacker()  
Z_Name$ = RemoveString(F_Name$, ".txt") + ".zip"
Debug "Archive: " + Z_Name$

If CreatePack(0, Z_Name$)      
    AddPackFile(0, F_Name$, F_Name$)    
    ClosePack(0)  
    Debug "OK"
    Debug FormatNumber(FileSize(Z_Name$), 0) + " octets"
Else
    Debug "KO"
EndIf

; Affichage archive avec programme externe (ici 7zip)
Zip_Prog$ = GetUserDirectory(#PB_Directory_Programs) + "\7-Zip\7zFM.exe"
If FileSize(Zip_Prog$) 
    RunProgram(Zip_Prog$, Z_Name$, "")
EndIf
Quand je pense que j'ai mis 20 ans avant d'oser mettre ne serais-ce qu'un espace dans un nom de fichier (et même dépasser le 8+3) :mrgreen: et que maintenant Windows (et Linux) mangent de tout directement :P . Vive l'unicode et l'UTF-8 partout 8)

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 13:14
par Ar-S
@Marc56
Perso je ne mets toujours ni accent ni espace... On a parfois des surprises avec les pièces jointes, les batch etc..

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 13:48
par Marc56
Ar-S a écrit :@Marc56
Perso je ne mets toujours ni accent ni espace... On a parfois des surprises avec les pièces jointes, les batch etc..
Oui, je l'ai aussi fait et prôné, mais force est de constater que depuis pas mal d'années les systèmes se débrouillent très bien.
Les shells (CMD ou BASH etc) ajoutent des "" automatiquement si on utilise la complétion (tab).
Les batchs fonctionnent bien (et ça permet par exemple de mettre une date dans le nom des rapports de log pour avoir des noms dynamiques)
Les mails encodent parfaitement les noms de pièce jointes avec accents.
Plus de problème depuis qu'on ne traine plus de programmes 16 bits ne connaissant que le 8+3
Il faut juste respecter les 9 caractères interdits (certains programmes ne savent pas les exclure et plantent)
Je suis vieux, mais j’évolue (lentement) et n'hésite pas à remettre en question certaines de mes certitudes dès lors que je n'ai plus rencontré de problème (notamment depuis que tous les systèmes Windows sont passés en NTFS)
Pour l'instant, aucun retour d'utilisateur n'ayant pas réussi à ouvrir un programme ou une pièce jointe.

:wink:

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 14:31
par Jacobus
En fait ça craint...
mais ce n'est pas un problème de la lib Packer() et c'est rassurant car ça veut dire que le process employé est bon.
Je compresse mes dossiers en zip ou en 7z, puis:
Si j'ouvre mes archives avec l'explorateur Windows => les accents sont remplacés par des trucs zarbis.
Si j'ouvre mes archives avec 7Zip => c'est nickel.
exemple:
décompressé avec 7z -> Feuilles d'érable.jpg
décompressé avec Windows -> Feuilles dÔÇÖ├®rable.jpg
:?

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 14:52
par Marc56
Oui, c'est ce que je vois aussi, mais apparemment cela vient du "dézzipeur" interne à Windows, car l'archive créée avec PB est parfaitement bien lue et décompactée avec accents avec d'autres programmes (7Zip, WinRar, Total Commander...)

Le pire est que Windows est capable de zipper les accents (Envoyer vers > Dossier compressé)

Et si on fait une archive Zip avec 7zip, elle est ok avec Windows :|
pareil avec winrar: un .zip avec des fichier avec accents est lisible dans le zip windows

:arrow: Donc il y a un truc qui ne va pas dans la lib zip de PB

Re: Changer les noms de fichiers avec accents

Publié : mar. 05/mai/2020 15:08
par Jacobus
Il faut que je fasse plusieurs tests avec les différents plugins.
J'ai eu les mêmes erreurs en utilisant #PB_PackerPlugin_Lzma
Sinon il faudra que je fournisse 7z (ou que je le conseille fortement) aux utilisateurs du programme...

7zip utilise LZMA2, et lorsque tu utilises Zip inclus dans 7z, les noms de fichiers avec accents sont identifiés UTF-8.
Se pourrait-il que la lib Packer() ne prenne pas en compte le mode UTF-8 ??

Je verrais ça plus tard, il faut que je passe la tondeuse, que j'attache les tomates et retire les gourmands, et que je bine les aubergines.