luxian Posté(e) le 30 mars 2020 Partager Posté(e) le 30 mars 2020 Bonjour, Je souhaite faire un script bash qui renomme une arborescence de fichiers selon tout un tas de petites règles à passer. Mon gros problème est du type find . -type f | rename 's/[ (1)]//' qui supprime tous les espaces de tous les noms de répertoires en plus du "(1)" ... exemple : - gicler les (1), (2) des anciens doublons qui n'en sont plus - supprimer les "!", les "~", les "(" que le vulgus user crée dans ses fichiers word ou emails - etc ... Je ne veux pas de boucle while / for dans ce script ... non, je n'en veux pas. Mes commandes sont donc des regex (que je tente de commencer de comprendre), de l'usage de "rename", du "find", du "sed" (que j'entrave décidément pas depuis 3 h que je cherche) et du " | ". Mes problèmes ... Le plus gros : Je n'arrive pas à faire comprendre à ma regex comment traiter non pas "chaque caractère" mais "une chaine". Notamment, la commande find . -type f | rename 's/[ (1)]//gi' ... qui supprime tous les espaces de tous les noms de répertoires en plus du "(1)" ... Je n'arrive pas à faire comprendre à "rename" (et d'ailleurs même sed), comment ne chercher que la chaîne " (1)" qui a "un espace" + "(1)" ... ou (2), etc ... à la fin du fichier. Je veux ici supprimer les doublons qu'a tendance à créer Google Drive quand il s'empêtre les synchronisations avec 3 PC connectés Windows au même google drive. Et pour optimiser : J'aurai bien aimé fusionner == find . -type f | rename 's/é/e/gi' == et == find . type f | rename 's/è/e/gi' == ... sans me retrouver avec ee dans le nom à chaque fois que j'ai un "é" ou un "è" :( ... Je crois que j'ai testé toutes les combinaisons de == find . type f | rename 's/[éè]/e/gi' == sans succès (cette combinaison écrit des "ee" à chaque "é" ou "è" et des "eeee" si le nom contient "éè" :-( Précision, le système de fichier est ... ntfs / gvfs-fuse ... un répertoire Windows monté dans une machine virtuelle Ubuntu :) Que fais-je donc ? Je nettoie un Google-Drive, et une Dropbox lancée sous Windows 10 depuis une VM Ubuntu, et un disque dur de 2 To en 2 partitions (ntfs et ext4) monté quand à lui dans la dite VM Ubuntu :) J'ai vu pas mal d'exemple avec des boucles type for / while etc ... Je n'en veux pas. Car il faut que je puisse réemployer facilement une même commande, mais avec des paterns différents à chaque fois. Merci d'avance pour votre aide. Lien vers le commentaire Partager sur d’autres sites More sharing options...
ecatomb Posté(e) le 30 mars 2020 Partager Posté(e) le 30 mars 2020 Au lieu de: find . -type f | rename 's/[ (1)]//gi' Il doit falloir : find . -type f | rename 's/ *(1)//gi' Pour les regex * = caractère précédant présent 0 fois ou plus [0-9] = n'importe quel chiffre de 0 à 9 Donc tu pourrais faire ceci: find . -type f | rename 's/ *([0-9])//gi' Après la regex dépend un peu de la fonction utilisée (enfin d'où on l'utilise) et donc peu varier un peu. find find toto = chercher dans le répertoire toto find -type f = chercher un fichier Le | Redirige ce qui est affiché à la fonction qui suit ce trait sed sed 's/abc/d/' = remplace le texte "abc" par "d" sur la première occurence (sed gère les regex) rename "rename - Rename or delete a command" <= d'après le man Je me demande si tu ne confonds pas avec un "mv" (déplace mais sous le nom donné) mv toto tata = renomme le fichier toto en tata Lien vers le commentaire Partager sur d’autres sites More sharing options...
brice.wernet Posté(e) le 31 mars 2020 Partager Posté(e) le 31 mars 2020 J'ajoute que pour les regex, ( et ) sont des caractères reconnus, il faut les échapper (sauf si tu utilises sed...) La syntaxe que tu indiques pour la regex est une syntaxe sed. Voici un début pour sed: $ echo "copy (1).jpg" | sed 's/\(.*\)\([ ](1)\)\(\..*\)$/mv "\1\2\3" "\1\3"/' La syntaxe sed utilisée: s/match/remplacement/options (je n'ai pas mis d'options, mais je crois que "i" signifie insensible à la casse) Les \( et \) permettent de capturer des parties (qu'on rappelle ensuite par \1, \2, \3) match: \(.*\)\([ ](1)\)\(\..*\)$ \(.*\): capturer n'importe quoi (\1 - nom du fichier) \([ ](1)\): capturer " (1)" (\2) \(\..*\)$: capturer l'extension (\3) (un point, n'importe quoi puis la fin de ligne ($)) remplacement: mv "\1\2\3" "\1\3": remplacer le nom du fichier complet par le nom du fichier sans le " (1)" A charge du lecteur de gérer tous les autres cas et de généraliser le " (1)" par une classe de caractères ou un intervalle. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.