如何使用“变量”批量重命名文件?

如何使用“变量”批量重命名文件?

我使用 xmbc 观看电视节目。在开始使用 xmbc 之前,我批量下载了《死神》的前几季。我能说什么呢,我是一个动漫迷 ;-)。这些被命名为:“bleachxx.mp4”,其中 xx 是剧集编号(相对于整个系列,而不是季节。因此“bleach21.mp4”是第二季的第一集,也是第 21 集。但是,文件本身被分成各自的季节文件夹。

我知道您可以使用“重命名”命令批量重命名文件。经过多次尝试,我按照本指南操作后发现:http://tips.webdesign10.com/how-to-bulk-rename-files-in-linux-in-the-terminal我收到这个命令:

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

问题在于,该命令会将所有文件重命名为“Bleach S0XExx”,但由于文件具有总文件编号,bleach52.mp4 --> 'Bleach S03E52.mp4',而第 3 季显然没有 52 集。

那么,我想知道是否有任何方法可以将数学运算应用于文件重命名。这将解决问题,因为我可以用总数减去前几季的剧集数,从而得到季数。

例如:如果第 1 季有 20 集,那么 25-20=5,因此第 25 集是第 2 季的第 5 集,重命名将正常进行。

那么,有没有办法通过数学运算来改变重命名的值?

PS:很抱歉解释这么长,但我不确定如果不解释的话该如何解释或者我的问题是否会被清楚解释。

答案1

如果您足够热衷于修改正则表达式(在提供的示例中),那么我建议您更进一步,编写一个小脚本 - 比如,用 Python。这样,您将能够对文件名执行任何转换。

我估计 Python 脚本不会超过 15-20 行,所以这绝对不是一项艰巨的任务。仅使用正则表达式(正如您所尝试的那样)会受到更多限制。

以下是我对此类脚本的看法:

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

看起来我低估了脚本的大小(目前是 36 行),不过我确信如果你带着这段代码去 stackoverflow,你会得到很多更优雅的建议

我说了它可以在 15 行内完成……下面是 20 行,其中 5 行是配置 :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

答案2

我给你写了一个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()

我对 Python 还很陌生(这也是我写这篇文章的原因之一,为了练习),所以它可能不是世界上最好的脚本。但我在一些测试文件上试了一下,似乎有效。

只需将靠近顶部的行编辑episode_counts = ...为该季的最后一集数。我输入了前三集这一页。

将代码保存为类似的内容episode_renamer.py并将其与一起使用python episode_renamer.py /path/to/episodes/

答案3

存储库中有一个名为 Thunar 的文件管理器,它具有批量重命名选项。

请参阅此网站以了解更多信息: http://thunar.xfce.org/pwiki/documentation/bulk_renamer

您可以在软件中心或命令行中安装 thunar:

sudo apt-get install thunar

在 bash 中还有其他方法可以做到这一点,或者通过编写一些代码,但图形工具可能会更快地让您得到您想要的结果。

答案4

为了继续鞭打这匹马...如果这是一次性重命名,我会做一些一次性的事情,例如:

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

如果您要多次使用它,并且用于多种类型的情节......那么 python 是最佳选择,并且上述示例就很好。

相关内容