如何在捕获其他字符后替换所有点

如何在捕获其他字符后替换所有点

我正在尝试使用该perl-rename命令重命名一些节目。目前的格式看起来像这样:

series.S01E**.title.of.the.episode.mkv

星号是剧集编号的占位符。

我想像这样重命名它:

[Series] - S01E** - title of the episode.mkv

我已经成功地捕获了该系列的名称以及剧集的名称,但我不知道在匹配某些内容后如何替换这些点。

perl-rename 's/(\w+)\.(S\d{2}E\d{2})\./[\u$1] - $2 - /' -n *.mkv
                                     ^ No idea what to insert here

一通电话rename就是我的目标。标题的长度可以是任意可变的,所以我不能做(\w+)\.(\w+).../$1 $2... # match a word and a dot固定次数的事情。

我正在寻找的基本上是一个匹配word..

答案1

尝试:

perl-rename -n 's{(\w+)\.(S\d{2}E\d{2})\.(.*)(\.mkv)\Z}{
  "[\u$1] - $2 - " . ($3 =~ y/./ /r) . $4}es' ./*.mkv
  • perl基于的rename实现(全部源自rename脚本perl早在 1989 年的 perl 3 中就已经附带了),将作为参数给出的文件重命名为第一个参数中给出的代码$_修改后的值。perl
  • s{regex}{replacement}flagss/regex/replacement/flags,与的缩写相同$_ =~ s{regex}{replacement}flag。也就是说,替换运算符应用于$_包含文件要重命名的名称的变量。
  • 这里旗帜containse这意味着替换被解释为 perl 代码,该代码被e评估以生成替换。
  • 我们还使用该s标志来.匹配您通常想要使用的换行符,因为rename换行符与文件名中的任何字符一样有效。这也是为什么我们在主题末尾的匹配中使用\Z(matches at the end of the subject) 而不是$which perl,但也可能在主题末尾的换行符之前使用。但在这种情况下,它不会产生任何影响,因为所有文件名都以 结尾v,而不是换行符。
  • ($3 =~ y/./ /r)y将(又名)运算符应用于tr第三个捕获组。使用该r标志,替换不会就地应用($3无论如何都是只读的),而是r返回替换的结果。

就我个人而言,我会使用zsh'szmv代替:

autoload -Uz zmv
zmv -n '(*).(S<1-99>E<1-99>).(*)(.mkv)' '[${(C)1}] - $2 - ${3//./ }$4'

其中${(C)1}将之前部分中的每个单词(alnums 序列)大写./SXXEYY(例如更改foo.Bar-BAZ为)。Foo.Bar-Baz

优点rename

  • 只有一种实现(虽然有数十种变体rename)。
  • 它在进行任何重命名之前会进行一些健全性检查(例如,如果您同时拥有 aseries.S01E01.title x.mkv和,则会中止Serias.S01E01.title.x.mkv
  • rename如果您忘记了--(并非全部支持)或./前缀,则不存在 Perl 某些变体的任意命令注入漏洞。
  • 它还适用于非 ASCII 文件名(例如épisode大写的 to Épisode)。

答案2

sed正如or脚本一样, perl 脚本中perl可以有多个语句(用 分隔;,或使用多个选项) 。例如:-erename

$ touch 'my.series.name.S01E'{01..03}'.title.of.the.episode.mkv'
$ ls -l
total 6
-rw-r--r-- 1 cas cas   0 Jun  7 10:56 my.series.name.S01E01.title.of.the.episode.mkv
-rw-r--r-- 1 cas cas   0 Jun  7 10:56 my.series.name.S01E02.title.of.the.episode.mkv
-rw-r--r-- 1 cas cas   0 Jun  7 10:56 my.series.name.S01E03.title.of.the.episode.mkv

$ rename 's/\./ /g; s/ (mkv)$/.$1/; s/^(.*) (S\d\dE\d\d) /[\u$1] - $2 - /' *.mkv
$ ls -l
total 6
-rw-r--r-- 1 cas cas   0 Jun  7 10:57 [My series name] - S01E01 - title of the episode.mkv
-rw-r--r-- 1 cas cas   0 Jun  7 10:57 [My series name] - S01E02 - title of the episode.mkv
-rw-r--r-- 1 cas cas   0 Jun  7 10:57 [My series name] - S01E03 - title of the episode.mkv

重命名脚本:

  • .用空格替换所有字符(包括.mkv 扩展名之前的字符)

  • 将扩展名之前的空格更改回..目前,这仅适用于 .mkv 文件,但很容易将其更改为s/ (mkv)$/.$1/,例如,s/ (mkv|avi|mp4)$/.$1/如果您有其他容器格式的视频。

    如果您需要处理具有多个“扩展名”的文件名,例如.xyz.mp4,这将需要更多工作,并且很难区分剧集标题中的单词和“扩展名”,除非提前知道所有扩展名。

  • 将文件名的系列名称和剧集编号部分重新格式化为[Series] - SnnEnn -.剧集标题和扩展名在前两个命令之后保持原样。

注意:如果您编写任何其他处理这些文件的 shell 脚本,则必须小心地用双引号包含文件名的任何变量,因为它们都包含空格、[]字符。这没什么大不了的,因为无论如何你都应该引用你的变量。

顺便说一句,脚本中的语句rename可以是任何有效的 Perl 代码,甚至可以是use已安装的任何 Perl 模块。并非所有语句都必须直接更改文件名(例如,您可以使用代码来递增计数器,或者stat在文件名上运行以检查其大小或时间戳,或者其他任何内容 - 甚至查询数据库或进行 Web API 调用来发现如果文件名中缺少剧集标题)。任何更改$_都会更改文件名。

相关内容