Renomeia recursivamente todos os arquivos e pastas para o caso de título do terminal

5

Eu sou um novato e procurei em todos os lugares por isso, também tentei combinar um comando de renomeação em minúsculas com algum regex para obter o Title Case em vez de minúsculas, mas não obtive muito sucesso.

Este comando converte tudo (arquivos + pastas) dentro da pasta dada para minúsculas:

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

E esta é a minha tentativa no título, funciona, mas não é recursiva:

find . -name "*.flac" -print0 | while read -d $'
while IFS= read -r -d '' file; do mv -b -- "$file" "${file,,}"; done < <(find . -depth -name '*[A-Z]*' -print0)
' file; do rename 's/(^|[\s\(\)\[\]_-])([a-z])/$1\u$2/g' *; done

Essas são apenas algumas das minhas tentativas, se houver soluções melhores e mais curtas eu gostaria muito delas.

Você poderia me ajudar? Obrigado antecipadamente!

EDIT: eu esqueci de mencionar, meus arquivos são assim: "09 - o caminho para casa - Amy MacDonald.flac"; deve ser renomeado para "09 - The Road To Home - Amy Macdonald.flac". Observe como já existem palavras maiúsculas no título, bem como letras maiúsculas no meio de uma palavra.

    
por BlackR 24.02.2015 / 14:10

2 respostas

5

Para usar o script abaixo, você não precisa mais do que a capacidade de colar:)

Como usar

  1. Cole o script abaixo em um arquivo vazio, salve-o como (por exemplo) rename_title.py
  2. torne-o executável (por conveniência) chmod u+x rename_title.py
  3. Execute-o com o diretório para renomear como argumento:

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

O script

#!/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)

Exemplos:

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

E mais complexo, excluindo ["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

torna-se:

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

etc, ele simplesmente torna todos os arquivos e pastas (recursivamente) Title Case, extensões em minúsculas.

EDIT: Eu adicionei todos os artigos, conjunções e preposições que não precisam ser capitalizados de acordo com as regras de capitalização para títulos de músicas.

    
por Jacob Vlijm 24.02.2015 / 15:11
1

Se você usar find ' -exedir , os nomes receberão qualquer comando com os principais componentes do nome de caminho removido, como ./sOmE fILE . Você poderia, então, intitular cada sequência de caracteres de palavras precedida por / ou espaços em branco, por exemplo,

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