web-dev-qa-db-fra.com

Renommer récursivement tous les fichiers et dossiers en Title Case à partir du terminal

Je suis un débutant et j’ai cherché partout cela, j’ai également essayé de combiner une commande de changement de nom en minuscule avec une expression rationnelle pour obtenir la casse de titre au lieu de minuscule, mais j’ai échoué.

Cette commande convertit tout (fichiers + dossiers) du dossier donné en minuscule:

while IFS= read -r -d '' file; do mv -b -- "$file" "${file,,}"; done < <(find . -depth -name '*[A-Z]*' -print0)

Et ceci est ma tentative de cas de titre, cela fonctionne, mais ce n'est pas récursif:

find . -name "*.flac" -print0 | while read -d $'\0' file; do rename 's/(^|[\s\(\)\[\]_-])([a-z])/$1\u$2/g' *; done

Ce ne sont là que quelques-unes de mes tentatives. S'il existe de meilleures solutions plus courtes, je les préférerais plutôt.

Pourriez-vous s'il vous plaît m'aider? Merci d'avance!

EDIT: J'ai oublié de mentionner, mes fichiers ressemblent à ceci: "09 - The Road to Home - Amy MacDonald.flac"; devrait être renommé "09 - The Road To Home - Amy Macdonald.flac". Remarquez qu'il existe déjà des mots avec titre en majuscule ainsi que des lettres majuscules au milieu d'un mot.

5
BlackR

Pour utiliser le script ci-dessous, vous n'avez pas besoin de plus que la possibilité de coller :)

Comment utiliser

  1. Collez le script ci-dessous dans un fichier vide, enregistrez-le sous le nom de rename_title.py
  2. le rendre exécutable (pour des raisons de commodité) chmod u+x rename_title.py
  3. Exécutez-le avec le répertoire à renommer en argument:

    /path/to/rename_title.py <directory/to/rename>
    

Le scénario

#!/usr/bin/env python3
import os
import sys
import shutil

directory = sys.argv[1]

skip = ["a", "an", "the", "and", "but", "or", "nor", "at", "by", "for", "from", "in", "into", "of", "off", "on", "onto", "out", "over", "to", "up", "with", "as"]
replace = [["(", "["], [")", "]"], ["{", "["], ["}", "]"]]
def exclude_words(name):
    for item in skip:
        name = name.replace(" "+item.title()+" ", " "+item.lower()+" ")
    # on request of OP, added a replace option for parethesis etc.
    for item in replace:
        name = name.replace(item[0], item[1])
    return name

for root, dirs, files in os.walk(directory):
    for f in files:
        split = f.find(".")
        if split not in (0, -1):
            name = ("").join((f[:split].lower().title(), f[split:].lower()))
        else:
            name = f.lower().title()
        name = exclude_words(name)
        shutil.move(root+"/"+f, root+"/"+name)
for root, dirs, files in os.walk(directory):
    for dr in dirs:
        name = dr.lower().title()
        name = exclude_words(name)
        shutil.move(root+"/"+dr, root+"/"+name)

Exemples:

a file > A File
a fiLE.tXT > A File.txt
A folder > A Folder
a folder > A Folder

Et plus complexe, à l'exclusion de ["a", "an", "the", "and", "but", "or", "nor", "at", "by", "for", "from", "in", "into", "of", "off", "on", "onto", "out", "over", "to", "up", "with", "as"]:

down BY the rIVER for my uncLE To get water.TXT

devient:

Down By the River for My Uncle to Get Water.txt

etc, il fait simplement tous les fichiers et dossiers (récursivement) Title Case, extensions minuscules.

EDIT: J'ai ajouté tous les articles, conjonctions et prépositions qui n'ont pas besoin d'être capitalisés conformément aux règles de capitalisation des titres de chansons.

5
Jacob Vlijm

Si vous utilisez -exedir de find, alors les noms sont passés à n'importe quelle commande avec les composants principaux du chemin d'accès supprimés, comme ./sOmE fILE. Vous pouvez ensuite mettre en casse chaque séquence de caractères Word précédée du signe / au début ou par des espaces, par exemple.

find path/ -execdir rename -nv -- 's/(?<=[\/\s])(\w)(\w*)/\u$1\L$2/g' {} +
1
steeldriver