由于看动漫对高画质有喜好,于是经常需要自行下载番剧和字幕,不过很多时候番剧和字幕的名称并不是配套的,字幕往往是另外下载而来,所以每看一集都要拉一次字幕进去,这可不是懒人的风格,于是就需要自己将字幕重命名了,手动一个个重命名也是麻烦,还是费点心思用命令行批量重命名来得方便。

重命名

时常会遇到这样的字幕和番剧:

重命名前

字幕和番剧的名称都是有规律的,于是可以使用下面的命令进行批量重命名:

1for i in $(seq -w 1 12); do TARGET=(*\ ${i}\ *.mkv) ; mv *\[${i}\]*sc.ass "${TARGET%mkv}ass" ; done

重命名之后就是这样的了:

重命名后

原理

这条命令还是很简单的,不得不感慨命令行的强大:

1for i in $(seq -w 1 12); do TARGET=(*\ ${i}\ *.mkv) ; mv *\[${i}\]*sc.ass "${TARGET%mkv}ass" ; done

这条命令主要是使用for循环处理:

1for i in $(seq -w 1 12);
2	do
3		...
4	done

这是命令主体,$(seq -w 1 12)使用seq命令,可以生成一串规则的数字,格式为:

1# 不指定首数则默认从1开始
2Seq [选项] 尾数
3
4# 指定首数和尾数
5Seq [选项] 首数  尾数

例如,使用:

1seq 1 12

可以生成112之间的数字:

 11
 22
 33
 44
 55
 66
 77
 88
 99
1010
1111
1212

seq还支持自定义增量,格式是:

1Seq [选项] 首数 增量 尾数

seq支持类似printf的格式,所以可以使用下面的格式来输出需要的0112样式的数字:

1seq -f "%02g" 1 12

%g是指输出数字,2指输出结果占用两个位宽,0指空白部分用数字0进行填充,最后输入如下:

 101
 202
 303
 404
 505
 606
 707
 808
 909
1010
1111
1212

也可以使用-s参数把默认的\n分隔字符改为空格

1seq -s " " -f "%02g" 1 12

输出结果如下:

101 02 03 04 05 06 07 08 09 10 11 12

不过在此不必这样麻烦地更改格式,使用\n进行分隔,for函数也能正确识别。

而需要输出0012这样的数字,其实使用-w参数更简便,-w参数的含义是--equal-width,即在列前添加0,使得宽度相同,所以上面的命令还可以简化为:

1seq -w 1 12

接下来的

1TARGET=(*\ ${i}\ *.mkv)

是指将mkv文件的名称存储为字符串TARGET的值,由于名称中存在其他数字,可能跟匹配的${i}会有混淆,所以在前后加上了空格作为区别。注意,这里存储的值包括扩展名,所以在后面使用到这个字符串的时候需要这样用:

1${TARGET%mkv}ass

%mkv即删除掉字符串后面的mkv字符,然后再加上ass字符。

1mv *\[${i}\]*sc.ass "${TARGET%mkv}ass"

mv中的重命名字幕使用的并不是*${i}*sc.ass,而是*\[${i}\]*sc.ass,是因为字幕文件名其他地方也包含了数字,这是为了避免冲突,而因为添加的字符是[],所以需要使用反斜杠\进行转义,最后的sc只是为了加强识别,因为有时候会有简体繁体字幕同时出现。

最后一点需要注意的是,如果重命名出现下面这样的报错:

1mv: target '....ass' is not a directory

或者

1mv: 目标“....ass”不是目录

这样的提示,那么应该把文件名加上双引号,即:

1for i in $(seq -w 1 12); do TARGET=(*\ ${i}\ *.mkv) ; mv *\[${i}\]*sc.ass "${TARGET%mkv}ass" ; done

出现这样的报错的原因是文件名中包含空格,而在mv命令中,a .ass这样的文件名会被识别成a.ass,然后最终的命令就变成了

1mv a .ass a.ass

而由于是移动两个文件到第三个参数,那么第三个参数a.ass就会被当成目录,所以就会有这样的报错。

而如果是出现下面的报错:

1mv: 无法获取'*\[01\]*.ass' 的文件状态(stat): No such file or directory
2mv: 无法获取'*\[02\]*.ass' 的文件状态(stat): No such file or directory
3...

出现原因是因为在mv 原名 新名中,原名用了双引号,去掉即可。