Renommer en masse les répertoires pour déplacer l'année de la fin au début

11

Je me bats actuellement avec certains dossiers de musique. Une fois , je décidé de les nommer en suivant le modèle: artist - album - year. J'ai réalisé aujourd'hui que ce n'était pas une décision intelligente et je veux maintenant nommer mes répertoires en suivant le modèle: year - artist - albumcar ils apparaîtront ensuite dans l'ordre croissant lorsqu'ils seront répertoriés.

J'ai commencé à renommer à la main mais, avec environ 700 dossiers, il doit y avoir un moyen plus simple; J'ai essayé d'utiliser gprenamemais je ne suis pas si bon en script regex et bash ...

Y a-t-il quelqu'un qui pourrait m'aider à épargner mes pauvres doigts?

Quelques exemples:

Aes Dana - Memory Shell - 2004 
Anja Schneider & GummiHz - Back To Back (Remixes Part 2) - 2009

deviendrait

2004 - Aes Dana - Memory Shell
2009 - Anja Schneider & GummiHz - Back To Back (Remixes Part 2)

EDIT: Certains noms d'artiste et d'album ont des caractères spéciaux comme And.Idou Kool & The Gang. Bien que chaque répertoire ait un -séparateur.

TazMayhem
la source
2
Veuillez ajouter quelques exemples de noms de répertoire et de sortie attendue.
muru
Par exemple: J'ai "Aes Dana - Memory Shell - 2004" et j'aimerais avoir "2004 - Aes Dana - Memory Shell"
TazMayhem
1
Vous savez comment modifier la question, alors pourquoi ne l'ajoutez-vous pas à la question? De plus, y a-t-il des noms d'album ou d'artiste -en eux?
muru
Le nom est-il organisé par le délimiteur "-" par définition, et peut-il apparaître ailleurs dans le nom?
Jacob Vlijm
J'ai tendance à rediriger les dossiers source vers un fichier texte, puis à utiliser vim. Je crée une macro pour créer un deuxième paramètre pour chaque ligne avec les composants appropriés du dossier source dans le bon ordre, puis j'utilise une autre macro pour mettre mv au début de chaque ligne. Je pourrais même aller jusqu'à prendre d'abord une copie de la structure des dossiers au cas où je ferais un gâchis de dossiers perdus.

Réponses:

16

En supposant que vous ayez accès à perl rename(généralement disponible dans Ubuntu - merci à @Serg pour clarifier la différence. En cas de doute, appelez /usr/bin/renameet vous devriez obtenir le bon), vous pouvez utiliser:

rename -n 's/(.*) - (\d{4})\//$2 - $1/' */

Supprimez -naprès le test pour renommer les répertoires. Cela suppose que tous les albums datent de 1000 à 9999. Probablement raisonnable ...

Explication

  • s/old/newremplacer oldparnew
  • (.*)enregistrer un nombre quelconque de caractères pour faire référence comme $1plus tard
  • (\d{4})\/enregistrez quatre chiffres à la fin de la ligne pour vous y référer $2ultérieurement.
  • */ correspondre à tous les répertoires (pas aux fichiers - merci à @muru pour son aide!)
Zanna
la source
3
Peut-être faire */pour ne faire correspondre que les répertoires.
muru
@muru, il ne semble pas fonctionner! Qu'est-ce que je fais bêtement?
Zanna
1
@Zanna i éclaircir ce à quoi ils se réfèrent est le fait que certains obus comme mkshont un appel intégré rename. Il suffit de le remplacer par un chemin complet ou d'appeler prenamepour appeler le renommage Perl
Sergiy Kolodyazhnyy
1
@Zanna Trouvé ce bit intéressant: unix.stackexchange.com/a/229248/85039 TL; DR : Le renamen'est pas "parfois appelé prename" mais apparemment ce sont deux "branches" du même script, une qui n'est pas maintenue par Debian, et l'autre qui l'est. Donc voilà . . . c'est beaucoup de désordre - certains shells ont le leur rename, le paquet perl a le sien rename, et debian lui-même fournit un paquet séparé
Sergiy Kolodyazhnyy
1
@Zanna Je pensais du programme appelé rename.uldans unix.stackexchange.com/q/229230/21167
Zwol
6

Un script Python simple peut faire un tel travail:

$ tree
.
├── Aes Dana - Memory Shell - 2004
├── Anja Schneider & GummiHz - Back To Back (Remixes Part 2) - 2009
└── rename_dirs.py

2 directories, 1 file
$ ./rename_dirs.py */
$ tree
.
├── 2004 - Aes Dana  -  Memory Shell 
├── 2009 - Anja Schneider & GummiHz  -  Back To Back (Remixes Part 2) 
└── rename_dirs.py

Contenu du script:

#!/usr/bin/env python
from shutil import move;
import sys

for i in sys.argv[1:] :
    parts = i[:-1].split('-')
    year = parts[-1].strip()
    new_name = year + " - " + " - ".join(parts[:-1]).strip()
    move(i,new_name)

Comment cela fonctionne:

  • L'astuce principale est que nous exécutons le script à partir du même répertoire où résident les cibles. Nous passons également */pour ne fournir que des répertoires comme arguments du script
  • Le script parcourt tous les arguments de la ligne de commande, décomposant chaque nom de fichier en liste de chaînes au -caractère. Le nouveau nom de fichier est construit à partir des parties que nous avons extraites.
  • move()la fonction du shutilsmodule est ce qui renomme réellement les répertoires

Notez l'utilisation: ./rename_dirs.py */

Sergiy Kolodyazhnyy
la source