我一直在尝试批量重命名一堆文件,以便它们保持一致并符合我想出的名称结构。例如,我正在重命名漫画,所以我有一个如下所示的目录:
$ls *.cbr
Injustice - Gods Among Us 001 (2013) (Digital) (K6 of Ultron-Empire).cbr
Injustice - Gods Among Us 002 (2013) (Digital) (K6 of Ultron-Empire).cbr
Injustice - Gods Among Us 003 (2013) (Digital) (K6 of Ultron-Empire).cbr
我的目标是重命名文件,使它们看起来如下所示:
Injustice - Gods Among Us 001.cbr
Injustice - Gods Among Us 002.cbr
Injustice - Gods Among Us 003.cbr
因此我尝试了以下方法:
rename -n 's/^\d{3}.\.cbr/^\ $1.cbr/' *.cbr
我以为通过界定到 3 位数发行号上的第一个设置,我就可以更改为从第一行开始重命名所有内容(Injustice - God Among Us),然后添加 3 位数发行号 (\d{3}),这样一切都会顺利。不用说,事实并非如此。
尽管我希望得到一些关于如何解决这个问题的指导,但我真的想更好地理解如何利用前缀表达式以供将来使用。
答案1
我认为你误解了克拉()线锚的含义^
- 它并不意味着“寻找图案从以下正则表达式开始”,这意味着“寻找一个线从以下内容开始图案'——这当然不会匹配任何列出的文件名,因为 001 ... 003 是名称的一部分。
你可能想到的是 Perl 的环视四周构造 - 例如,要将匹配限制为名称中前 3 位数字序列之后的部分,可以使用(?<=\d{3})
向后看。类似地,要将匹配限制在后缀之前的部分,.cbr
可以使用前瞻 (?=\.cbr)
最后,您可以匹配后视和前视之间的任何字符,即.*
,并将其替换为空:
$ rename -nv 's/(?<=\d{3}).*(?=.cbr)//' *.cbr
Injustice - Gods Among Us 001 (2013) (Digital) (K6 of Ultron-Empire).cbr renamed as Injustice - Gods Among Us 001.cbr
Injustice - Gods Among Us 002 (2013) (Digital) (K6 of Ultron-Empire).cbr renamed as Injustice - Gods Among Us 002.cbr
Injustice - Gods Among Us 003 (2013) (Digital) (K6 of Ultron-Empire).cbr renamed as Injustice - Gods Among Us 003.cbr
请注意,通常有几种不同的方法来匹配和重命名一组特定的文件 - 我不确定这是最有效或最强大的,但我希望它能说明我思考你所追求的。
答案2
我假设(2013) (Digital) (K6 of Ultron-Empire)
字符串在所有文件中都是固定的,实际上你不需要任何太复杂的东西:
$ ls
Injustice - Gods Among Us 001 (2013) (Digital) (K6 of Ultron-Empire).cbr
Injustice - Gods Among Us 002 (2013) (Digital) (K6 of Ultron-Empire).cbr
Injustice - Gods Among Us 003 (2013) (Digital) (K6 of Ultron-Empire).cbr
$ rename 's/ \(2013\) \(Digital\) \(K6 of Ultron\-Empire\)//g' *
$ ls
Injustice - Gods Among Us 001.cbr Injustice - Gods Among Us 003.cbr
Injustice - Gods Among Us 002.cbr
为了实用,我放弃了灵活性。如果你想删除中间的所有内容,(...)
你甚至可以使用更巧妙的方法:
rename -n 's/ ([(].*Digital.*[)])//g' *
此外,你的正则表达式实际上并没有选择任何东西。我会读这个答案了解其\d{3}
工作原理。