Renomear diretórios em massa para mover o ano do início ao fim

11

Atualmente, estou lutando com algumas pastas de música. Uma vez eu decidi nomeá-los seguindo o padrão: artist - album - year. Percebi hoje que essa não era uma jogada inteligente e agora quero nomear meus diretórios seguindo o padrão: year - artist - albumcomo eles aparecerão em ordem crescente quando listados.

Comecei a renomear manualmente, mas, com aproximadamente 700 pastas, deve haver uma maneira mais simples; Eu tentei usar, gprenamemas não sou tão bom em regex e bash scripting ...

Existe alguém que possa me ajudar a poupar minhas pobres pontas dos dedos?

Alguns exemplos:

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

se tornaria

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

EDIT: Alguns nomes de artistas e álbuns têm caracteres especiais como And.Idou Kool & The Gang. Embora todo diretório tenha -como separador.

TazMayhem
fonte
2
Por favor, adicione alguns exemplos de nomes de diretório e saída esperada.
31717 muru
Por exemplo: Eu tenho "Aes Dana - Memory Shell - 2004" e gostaria de ter "2004 - Aes Dana - Memory Shell"
TazMayhem 29/17/17
1
Você sabe como editar a pergunta. Por que não adiciona isso à pergunta? Além disso, algum dos nomes de álbuns ou artistas tem -neles?
muru 29/03
O nome é organizado pelo delimitador "-" por definição e possivelmente ocorre em outro lugar no nome?
Jacob Vlijm 29/03
Geralmente, as pastas de origem são redirecionadas para um arquivo de texto e, em seguida, uso o vim. Crio uma macro para criar um segundo parâmetro para cada linha com os componentes relevantes da pasta de origem na ordem correta, depois uso outra macro para colocar mv no início de cada linha. Eu posso até tirar uma cópia da estrutura de pastas primeiro, caso eu tenha feito uma bagunça / pastas perdidas.

Respostas:

16

Supondo que você tenha acesso ao perl rename(geralmente disponível no Ubuntu - obrigado a @Serg por esclarecer a diferença. Em caso de dúvida, ligue /usr/bin/renamee você deve obter o caminho certo), você pode usar:

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

Remova -napós o teste para renomear os diretórios. Isso assume a data de todos os álbuns entre 1000 e 9999. Provavelmente razoável ...

Explicação

  • s/old/newsubstitua oldpornew
  • (.*)salve qualquer número de caracteres para fazer referência mais $1tarde
  • (\d{4})\/salve quatro dígitos no final da linha para fazer referência mais $2tarde.
  • */ corresponder a todos os diretórios (não arquivos - graças à @muru pela ajuda!)
Zanna
fonte
3
Talvez faça */apenas para corresponder aos diretórios.
29717 muru
@uru parece não funcionar! O que estou fazendo estupidamente?
Zanna
1
@ Zanna eu fina o que eles se referem é o fato de que algumas conchas como mkshtêm um built-in chamado rename. É suficiente substituí-lo por caminho completo ou ligar prenamepara chamar o nome do Perl #
Sergiy Kolodyazhnyy
1
@Zanna Achei esse trecho interessante: unix.stackexchange.com/a/229248/85039 TL; DR : O nome renamenão é "às vezes chamado prename", mas aparentemente são dois "ramos" do mesmo script, um que não é mantido pelo Debian, e o outro que é. Então sim . . . é um monte de confusão - algumas conchas têm o seu próprio renamepacote, perl tem a sua própria rename, e Debian em si oferece pacote separado
Sergiy Kolodyazhnyy
1
@Zanna eu estava pensando do programa referido como rename.ulem unix.stackexchange.com/q/229230/21167
Zwol
6

Um script Python simples pode fazer esse trabalho:

$ 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

Conteúdo do 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)

Como isso funciona:

  • O truque principal é que executamos o script a partir do mesmo diretório em que os destinos residem. Também passamos */a fornecer apenas diretórios como argumentos para o script
  • O script itera sobre todos os argumentos da linha de comando, dividindo cada nome de arquivo na lista de cadeias de -caracteres. O novo nome do arquivo é construído com as partes extraídas.
  • move()função do shutilsmódulo é o que realmente renomeia os diretórios

Observe o uso: ./rename_dirs.py */

Sergiy Kolodyazhnyy
fonte