Como renomear arquivos em lote com “variáveis”?

Como renomear arquivos em lote com “variáveis”?

Eu uso o xmbc para ver meus programas de TV. Antes de começar a usar o xmbc, baixei em lote as primeiras temporadas de “Bleach”. O que posso dizer, sou fã de anime ;-). Eles são nomeados: "bleachxx.mp4" onde xx é o número do episódio em relação aosérie inteira, não para a temporada. então "bleach21.mp4" é o primeiro episódio da segunda temporada e o 21º no geral. Os próprios arquivos são, no entanto, divididos em suas próprias pastas de temporada.

Eu sei que você pode usar o comando "renomear" para renomear arquivos em lote. Depois de muito mexer nele usando este guia:http://tips.webdesign10.com/how-to-bulk-rename-files-in-linux-in-the-terminalEu recebi este comando:

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

O problema é que o comando renomeará todos os arquivos para “Bleach S0XExx”, mas como os arquivos têm os números gerais dos arquivos, Bleach52.mp4 -> ‘Bleach S03E52.mp4’ quando obviamente não há 52 episódios na 3ª temporada.

Gostaria de saber, então, se existe alguma forma de aplicar operações matemáticas na renomeação de arquivos. Isso resolveria o problema, pois eu poderia subtrair o número de episódios das temporadas anteriores pelo número total e, essencialmente, obter o número da temporada.

Exemplo: se houver 20 episódios na 1ª temporada, então 25-20=5, então o 25º episódio é o 5º da 2ª temporada e a renomeação ocorreria normalmente.

Então, existe alguma maneira de alterar os valores de renomeação aplicando operações matemáticas?

PS Sinto muito pela longa explicação, mas não tinha certeza de como fazê-lo ou se minha pergunta ficaria clara sem ela.

Responder1

Se você é dedicado o suficiente para mexer com expressões regulares (no exemplo fornecido), sugiro dar um passo adiante e escrever um pequeno script - digamos, em Python. Desta forma você poderá realizar absolutamente qualquer transformação nos nomes dos arquivos.

Eu estimaria que o script python não teria mais do que 15 a 20 linhas, então definitivamente não é uma tarefa enorme. Usar apenas regexps, como você está tentando, é muito mais limitado.

Aqui está minha opinião sobre esse script:

#!/usr/bin/python
import os,re

files = os.listdir('.')

SEASONS = (
 (1, 1, 3), # the format is - season number, first episode, last episode
 (2, 50,52),
 (3, 53,55),
 (4, 56,99),
)

for f in files:
    # skip all files which are not .mp4
    if not f.endswith(".mp4"):
        continue

    # find the first number in the filename
    matches = re.findall("\d+", f)
    if not len(matches):
       print "skipping", f
    num = int(matches[0])

    for season in SEASONS:
        if num <= season[2]:
            season_num = season[0]
            ep_num = num - season[1] + 1
            new_file_name = "BleachS%02dE%02d.mp4" % (season_num, ep_num)
            # This is for testing
            print "%s ==> %s" % (f, new_file_name)
            # Uncomment the following when you're satisfied with the test runs
            # os.rename(f, new_file_name)
            break

print "Done"

Parece que subestimei o tamanho do script (são 36 linhas atm), mas tenho certeza que se você for ao stackoverflow com este código, obterá muitas sugestões que são muito mais elegantes

E só porque eu disse que pode ser feito em 15 linhas... o seguinte são 20 linhas, sendo 5 de configuração :P

#!/usr/bin/python
import os, re, glob

SEASONS = (
 {'num':1, 'first':1, 'last':3}, # the format is - season number, first episode, last episode
 {'num':2, 'first':50, 'last':52},
 {'num':3, 'first':53, 'last':55},
 {'num':4, 'first':56, 'last':99},
)

files = glob.glob('bleach*.mp4')
for f in files:
    num = int(re.findall("\d+", f)[0])  # find the first number in the filename
    for season in SEASONS:
        if num > season['last']: continue
        new_file_name = "BleachS%02dE%02d.mp4" % (season['num'], num - season['first'] + 1)
        print "%s ==> %s" % (f, new_file_name) # This is for testing
        # os.rename(f, new_file_name) # Uncomment this when you're satisfied with the test runs
        break

Responder2

Eu escrevi para você um script python

import sys
import os
import glob
import re

def rename():
    episode_counts = (0, 20, 41, 63)
    episode_pairs = []
    for index, num in enumerate(episode_counts):
        if index < len(episode_counts) - 1:
            episode_pairs.append((num, episode_counts[index+1]))

    episodes = glob.glob(os.path.join(sys.argv[1], '*'))

    for episode in episodes:
        match = re.search('.*(\d{2}).*$', os.path.basename(episode))
        episode_num = match.group(1)

        for season, pair in enumerate(episode_pairs):
            if int(episode_num) in range(pair[0]+1, pair[1]+1):
                dirname = os.path.dirname(episode)
                path = os.path.join(dirname, 'Bleach S{0}E{1}'.format(season+1, episode_num))
                os.rename(episode, path)

if __name__ == "__main__":
    rename()

Sou realmente novo em python (e é em parte por isso que escrevi isso, para praticar), então provavelmente não é o melhor script do mundo. Mas tentei em alguns arquivos de teste e parece funcionar.

Basta editar a linha próxima ao topo episode_counts = ...dos números dos últimos episódios de uma temporada. Eu coloquei os três primeiros deesta página.

Salve o código como algo parecido episode_renamer.pye use-o com python episode_renamer.py /path/to/episodes/.

Responder3

Existe um gerenciador de arquivos chamado Thunar disponível no repositório que possui uma opção de renomeação em massa.

Consulte este site para mais informações: http://thunar.xfce.org/pwiki/documentation/bulk_renamer

Você pode instalar o thunar no Centro de Software ou na linha de comando com:

sudo apt-get install thunar

Existem outras maneiras de fazer isso no bash ou escrevendo algum código, mas uma ferramenta gráfica provavelmente fornecerá o que você deseja com mais rapidez.

Responder4

Para continuar açoitando este cavalo... se esta fosse uma renomeação única, eu faria algo descartável como:

cd /path/to/stuff
ls bleach*-lq.mp4 >x
paste x x >y
sed 's-^-mv -' <y >z
vim z    # or use your favorite editor
           # to rename the files manually
bash -x z
rm x y z

Se você for usá-lo mais de uma vez e em mais de um tipo de episódio... então python é a melhor opção, e os exemplos acima são ótimos.

informação relacionada