有什么方法可以改进这个正则表达式 oneliner?

有什么方法可以改进这个正则表达式 oneliner?

我有很多具有以下语法的视频文件:

TV.Show.Title.SXEY.Episode.Title.1080p.Uploader.mkv

其中SXEY不是常数。XY是取决于文件的数字。我想将它们重命名为

TV Show Title - SXEY - Episode Title.mkv

为此,我使用rename以下命令:

rename 's/\./\ -\ /;s/\./\ -\ /;s/\.(?!mkv)/\ /g;s/1080p.*(?=\.mkv)//g' *.mkv

该命令首先将前两个点转换为␣-␣,然后将所有其他点转换为空格,最后删除剧集标题末尾和文件扩展名之间的所有内容。

有什么想法可以改进吗?我想有一种方法可以只用一个正则表达式来转换前两个点。我相信rename它是一个 GNU 实用程序,因此并不存在于所有 Unix 系统上,我正在寻找一个更便携的替代方案。

答案1

很高兴这个问题实际上是关于 的regex,提出同样的问题我会避免打破我的大脑并且

for m in *.mkv; 
    do echo mv $m "$(awk -F'.' '{
        printf "%s %s %s - %s - %s %s.%s", $1, $2, $3, $4, $5, $6, $(NF)}' <<<$m)";
done

可预测、易于阅读,也易于修改输出字符串。只需删除echo

编辑

关于您在下面的评论sed,您可以使用相同的技术,只需处理您的文件名以进行输出,sed而不是awk

for m in *.mkv; 
    do echo mv $m "$(sed 's/\./ /1;s/\./ /1;s/\./ - /1;s/\./ - /1;s/\./ /1;s/\..*\././' <<<$m)";
done

答案2

你可以这样做:

$ rename -n 's/.(S\d+E\d+)./ - $1 - /; s/\./ /g; s/\.1080p.+\././' *mkv
TV.Show.Title.SXEY.Episode.Title.1080p.Uploader.mkv -> TV Show Title - SXEY - Episode Title 1080p Uploader mkv

或者也许是这样的:

$ rename -n 's/1080p.*\.//; s/\.(?!mkv)/ /g; s/S\d+E\d+/- $& -/' *mkv
TV.Show.Title.SXEY.Episode.Title.1080p.Uploader.mkv -> TV Show Title - SXEY - Episode Title.mkv

请注意,没有理由转义空格。因此,您可以简化命令,而无需实际更改正则表达式逻辑中的任何内容:

rename 's/\./ - /;s/\./ - /;s/\.(?!mkv)/ /g;s/1080p.*(?=.mkv)//g' *.mkv

.mkv但是,这会在您不想要的(您的原始版本也这样做)之前添加一个空格。所以也许这个:

rename -n 's/\./\ -\ /;s/\./\ -\ /;s/\.(?!mkv)/\ /g;s/ 1080p.*(?=.mkv)//g' *.mkv

如果您想要一个更便携的解决方案,您可以直接使用perl(perl 在几乎但不是全部 *nix 系统中可用):

perl -e 'for (@ARGV){$n=$_;s/1080p.*\.//;s/\.(?!mkv)/ /g;s/S\d+E\d+/- $& -/; rename($n,$_)}' *mkv

为了获得最大的可移植性,请在 shell 中完成所有操作(使用一点点sed):

for f in *mkv; do 
    k=${f//./ }
    k=$( printf '%s' "$k" | sed 's/S\([0-9][0-9]*E[0-9][0-9]\)/ - \1 -/')
    k=${k/ 1080p*/.mkv}
    mv -- "$f" "$k"
done

重要的提示: 你想做的是一个非常糟糕的主意。文件名中包含空格只会让您的生活变得更加困难,并使您将来想要对这些文件运行的任何类型的操作变得更加困难。请重新考虑。

答案3

尝试:

rename -v -n \
  's/\./ /g;s/S[X0-9]*E[Y0-9]*/- $& -/;s/ \d*p .* mkv$/.mkv/' *.mkv

输出给出了试运行,显示会发生什么,但尚未移动任何文件:

rename(TV.Show.Title.SXEY.Episode.Title.1080p.Uploader.mkv, 
       TV Show Title - SXEY - Episode Title.mkv)

如果输出看起来不错,请删除-v -n.自中期以来s替代是我的特别指定处理不太可能的演示字符串的方法“SXEY”, (代替《S02E23》或其他),将其替换为s/S\d*E\d*/- $& -/

rename 's/\./ /g;s/S\d*E\d*/- $& -/;s/ \d*p .* mkv$/.mkv/' *.mkv

笔记:

  • \当使用单引号“ ”时,不需要像“”这样转义空格' '

  • 上面的代码将所有.s 替换为空格,然后寻找S陈奕迅/piode 字符串,然后恢复最后一个文件扩展名.mkv.这避免了对固定长度的剧集和节目标题的需要。

答案4

不太确定您的实用程序是否支持捕获组,但使用它们将是一个可行的策略

([^.]+)[.]([^.]+)[.]([^.]+)[.]([^.]+)[.]([^.]+)[.]([^.]+)[.]([^.]+)[.]([^.]+)[.]([^.]+)

然后你会用

$1 $2 $3 - $4 - $5 $6.$7

此策略的优点是它实际上解析其他命名方案的语义,并允许对字段重新排序或省略。我更喜欢在可能的情况下使用字符组来转义字符,它[.]\..

相关内容