Renommez les fichiers pour qu’ils correspondent au nom du répertoire

J’ai un problème intéressant qui, je l’espère, peut être résolu facilement par des commandes shell. J’ai une arborescence de répertoires où les noms de répertoires sont significatifs et à l’intérieur de chaque répertoire se trouvent plusieurs fichiers, y compris un fichier .mp3.

Je voudrais renommer par lots tous les fichiers mp3 pour correspondre au nom du répertoire.

Par exemple, le répertoire de haut niveau ressemble à ceci:

Seans-iMac% ls 2006.James Lovelock: Gaia's Revenge 2006.Religion and stem cell research 2006.Stephen Schneider 2006.Tony Judt: Post-war Europe since 1945 2006.Water management 2007.'Here, Bullet' 2007.Alan Bennett 

Le contenu de chaque sous-répertoire est similaire, par exemple:

 Seans-iMac% cd "2006.Religion and stem cell research" Seans-iMac% ls details.txt lnl_20060605.mp3 synopsis.txt 

Je voudrais changer cela en ceci:

 Seans-iMac% ls details.txt 2006.Religion and stem cell research.mp3 synopsis.txt 

J’ai essayé une boucle for mais je n’arrive pas à obtenir les parameters corrects. Pour compliquer les choses, les noms de répertoire ont des espaces et certains ont des guillemets simples.

Si vous êtes sûr qu’il y a au plus un fichier mp3 dans chaque sous-répertoire, cela devrait le faire:

 for i in *; do mv "$i"/*.mp3 "$i/$i.mp3"; done 

Notez les guillemets doubles qui traitent des espaces.

 for d in 2???.* do mv "$d"/*.mp3 "$d/$d.mp3" done 

Le modèle glob génère les noms de répertoire qui vous intéressent, en préservant les espaces dans les noms. La commande mv suppose qu’il n’ya qu’un seul fichier .mp3 dans le sous-répertoire. Le premier argument sera donc développé avec le nom de fichier correct (les espaces seront conservés à nouveau) et le second argument aura la forme souhaitée. Notez que le *.mp3 est en dehors de la chaîne entre guillemets doubles; Cela permet l’expansion du nom de fichier. Notez que le nom du répertoire (qui peut contenir des espaces) est toujours entre guillemets pour éviter de perdre les espaces.

Soyez prudent lorsque vous utilisez des mécanismes autres qu’un glob pour générer les noms de répertoire. Ce n’est pas qu’ils ne peuvent pas être utilisés; juste que des soins sont nécessaires. Notez que les noms de répertoires contenant des nouvelles lignes risquent d’être encore plus problématiques que les espaces; Je renommerais ces répertoires afin qu’ils ne contiennent pas de nouvelles lignes (et il en va de même pour les noms de fichiers contenant des nouvelles lignes). Les espaces de début et de fin des noms peuvent également poser problème.

J’ai l’impression que vous utilisez tcsh en tant que shell. Étant donné que je ne suis pas un grand expert, ce qui suit génère un shell bash et utilise la syntaxe bash.

 bash -c 'find /path/to/root/dir -name \*.mp3 | while read file; do d=`dirname "$file"`; b=`basename "$d"`; echo mv -v "$file" "$d/$b.mp3";done' 

Cela ne fera aucune modification, il fait juste écho à la commande qui serait exécutée. Si, après double vérification, il fait bien ce que vous voulez, supprimez l’ echo devant la commande mv .

Ceci a les mêmes limitations que celles ci-dessus, s’il y a plus d’un fichier mp3 dans le répertoire, le dernier fichier (alphabétique) aura le nom du répertoire.mp3 et tous les autres fichiers mp3 seront écrasés (lire: perdu) .

La différence dans ce cas est que la structure des dossiers peut être nestede et pas nécessairement à un seul niveau.