17 votes

Comment renommer en masse des fichiers avec un encodage incorrect ou remplacer en masse des caractères mal encodés ?

J'ai un serveur debian et j'héberge de la musique pour une station de radio sur internet. J'ai des problèmes avec les noms de fichiers et les chemins car beaucoup de fichiers ont un encodage invalide, par exemple:

./music/Bändname - Some Title - additional Info/Bndname - 07 - This Title Is Cörtain, The EncÃding Not.mp3

Idéalement, j'aimerais supprimer tout ce qui n'est pas des lettres A-Z/a-z ou des chiffres 0-9 ou un tiret -/underscore _... Le résultat devrait ressembler à quelque chose comme ça:

./music/Bndname-SomeTitle-additionalInfo/Bndname-07-ThisTitleIsCrtain,TheEncdingNot.mp3

Comment atteindre cela pour un lot de nombreux fichiers et répertoires?

J'ai vu cette question similaire: bulk rename (or correctly display) files with special characters

Mais cela ne résout que l'encodage, je préférerais une approche plus stricte comme décrite ci-dessus.

16voto

r.e.s. Points 246

Je sais que ce n'est pas exactement ce que vous vouliez, mais si vous connaissez le codage d'origine, peut-être pouvez-vous utiliser convmv pour changer le codage en UTF-8, ce qui devrait résoudre la plupart des problèmes.

Cela a fonctionné pour moi sur un dossier avec quelques noms de fichiers polonais mal codés :

convmv -f cp1250 -t utf8 -r .

Notez que cette commande ne renomme pas réellement quoi que ce soit; ajoutez l'option --notest pour vraiment renommer les fichiers.

15voto

slhck Points 209720

Vous allez rencontrer des problèmes si vous voulez renommer des fichiers et des répertoires en même temps. Renommer simplement un fichier est assez facile. Mais vous devez vous assurer que les répertoires sont également renommés. Vous ne pouvez pas simplement mv Motörhead/Encöding Motorhead/Encoding car Motorhead n'existera pas au moment de l'appel.

Donc, nous avons besoin d'une traversée en profondeur de tous les fichiers et dossiers, puis de renommer uniquement le fichier ou le dossier actuel. Ce qui suit fonctionne avec GNU find et Bash 4.2.42 sur mon OS X.

#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
  d="$( dirname "$file" )"
  f="$( basename "$file" )"
  new="${f//[^a-zA-Z0-9\/\._\-]/}"
  if [ "$f" != "$new" ]      # si égaux, le nom est déjà propre, donc laissez-le tel quel
  then
    if [ -e "$d/$new" ]
    then
      echo "Avis : \"$new\" et \"$f\" existent tous deux dans "$d":
      ls -ld "$d/$new" "$d/$f"
    else
      echo mv "$file" "$d/$new"      # supprimez "echo" pour effectivement renommer les choses
    fi
  fi
done

Vous pouvez changer l'expression régulière en utilisant new="${f//[\\\/\:\*\?\"<>|]/}" si vous voulez remplacer tout ce que Windows ne peut pas gérer.

Enregistrez ce script sous le nom de rename.sh, rendez-le exécutable avec chmod +x rename.sh. Ensuite, appelez-le comme rename.sh /some/path.

Assurez-vous de résoudre tout collision de noms de fichiers (annonces de "Avis").

Si vous êtes absolument sûr qu'il effectue les bonnes substitutions, retirez le echo du script pour effectivement renommer les choses au lieu de simplement afficher ce qu'il fait.

Pour être sûr, je recommanderais de tester cela d'abord sur un petit sous-ensemble de fichiers.


Explication des options

Pour expliquer ce qui se passe ici :

  • -depth s'assurera que les répertoires sont parcourus en profondeur, de sorte que nous puissions "rembobiner" tout depuis la fin. Habituellement, find parcourt différemment (mais pas en largeur d'abord).
  • -print0 garantit que la sortie de find est délimitée par des zéros, afin que nous puissions la lire avec read -d '' dans la variable file. Cela nous aide à gérer toutes sortes de noms de fichiers bizarres, y compris ceux avec des espaces et même des sauts de ligne.
  • Nous obtiendrons le répertoire du fichier avec dirname. N'oubliez pas de toujours bien mettre entre guillemets vos variables, sinon tout chemin avec des espaces ou des caractères génériques casserait ce script.
  • Nous obtiendrons le nom de fichier réel (ou le nom de répertoire) avec basename.
  • Ensuite, nous supprimons tout caractère invalide de $f en utilisant les capacités de remplacement de chaîne de Bash. Invalide signifie tout ce qui n'est pas une lettre majuscule ou minuscule, un chiffre, une barre oblique (\/), un point (\.), un trait de soulignement ou un tiret.
  • Si $f est déjà propre (le nom nettoyé est identique au nom actuel), passez à côté.
  • Si $new existe déjà dans le répertoire $d (par exemple, vous avez des fichiers nommés resume et résumé dans le même répertoire), émettez un avertissement. Vous ne voulez pas le renommer, car, sur certains systèmes, mv foo foo pose problème. Sinon,
  • Nous renommons enfin le fichier (ou le répertoire) original avec son nouveau nom.

Étant donné que cela n'agira que sur la hiérarchie la plus profonde, renommer Motörhead/Encöding en Motorhead/Encoding se fait en deux étapes :

  1. mv Motörhead/Encöding Motörhead/Encoding
  2. mv Motörhead Motorhead

Cela garantit que toutes les substitutions sont faites dans le bon ordre.


Fichiers d'exemple et exécution de test

Supposons qu'il y ait des fichiers dans un dossier de base appelé test :

test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule

Voici la sortie d'un exécution en mode débogage (avec le echo devant le mv), c'est-à-dire les commandes qui seraient appelées et les avertissements de collision :

mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Avis : "resume" et "résumé" existent tous deux dans test/work :
-rw-r—r--  ...  ...  test/work/resume
-rw-r—r--  ...  ...  test/work/résumé

Remarquez l'absence de messages pour with-hyphen.txt, schedule, et test lui-même.

0voto

bonh Points 103

Je sais, tu as demandé à propos du renommage.

Mais tu peux facilement contourner le problème en utilisant un logiciel comme MusicBrainz Picard.

Il est capable d'identifier la musique (empreinte acoustique), de télécharger toutes les données nécessaires (y compris les images de couverture, lorsque disponibles) depuis l'immense base de données de MusicBrainz et de déplacer les fichiers afin que votre collection puisse correspondre à n'importe quel modèle que vous préférez. Je l'utilise depuis des années et cela a toujours parfaitement fonctionné avec n'importe quel script, du cyrillique à l'arabe; et bien sûr (au moins pour les scripts basés sur l'alphabet latin) il peut également faire la conversion en ASCII.

Avec cette approche, cela n'a pas vraiment d'importance à quel point votre collection est mal nommée/désordonnée, tant que les fichiers sont lisibles et complets.

(Ai-je mentionné que c'est gratuit? À la fois en terme de liberté et en terme de boisson gratuite? Tant le logiciel que la base de données..?)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X