如何通过在文件名中的任意位置填充数字来重命名文件?

myk*_*eli 4 shell bash rename

我在 Deepin(基于 Debian)系统上有一个目录,其中包含视频文件,如下所示:

SL Benfica - Match 1 vs FC Porto.mp4
SL Benfica - Match 2 vs FC Porto.mp4
...
SL Benfica - Match 20 vs FC Porto.mp4
...
SL Benfica - Match 100 vs FC Porto.mp4
SL Benfica - Match 101 vs FC Porto.mp4
Run Code Online (Sandbox Code Playgroud)

我想在中间的数字之前添加零,以便它们按

SL Benfica - Match 001 vs FC Porto.mp4
SL Benfica - Match 002 vs FC Porto.mp4
...
SL Benfica - Match 020 vs FC Porto.mp4
...
SL Benfica - Match 100 vs FC Porto.mp4
SL Benfica - Match 101 vs FC Porto.mp4
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个不依赖于模式的通用命令。只需搜索像 5 和 20 这样的数字,然后将它们更改为 005 和 020,在文件名的任何位置,甚至在文件名的末尾或开头。

ter*_*don 8

您可以使用perl-rename(应该可以sudo apt install rename在基于 Debian 的系统上安装)。使用这些文件作为输入:

$ ls -1
'anotherFile.m4a'    
'file 1 with 12 many 100 numbers 3.mp4'
'SL Benfica - Match 101 vs FC Porto.mp4'
'SL Benfica - Match 20 vs FC Porto.mp4'
'SL Benfica - Match 2 vs FC Porto.mp4'
Run Code Online (Sandbox Code Playgroud)

你可以运行:

rename 's/(\d+)(?=.*\.)/sprintf("%03d",$1)/eg' *
Run Code Online (Sandbox Code Playgroud)

这会将它们重命名为:

'anotherFile.m4a'
'file 001 with 012 many 100 numbers 003.mp4'
'SL Benfica - Match 002 vs FC Porto.mp4'
'SL Benfica - Match 020 vs FC Porto.mp4'
'SL Benfica - Match 101 vs FC Porto.mp4'
Run Code Online (Sandbox Code Playgroud)

注意如何100保持不变,其余的被填充。还要注意 4 in.m4amp4没有受到影响。

重要提示:首先运行命令-n以查看在实际重命名文件之前会发生什么:

rename -n 's/(\d+)(?=.*\.)/sprintf("%03d",$1)/eg' *
Run Code Online (Sandbox Code Playgroud)

正则表达式查找\d+至少一个.( ?=.*\.)之前的一位或多位数字 ( ) 的延伸。这是为了避免更改在扩展中找到的号码。但是,如果您的文件名没有扩展名,这将不起作用。如果您有这样的文件,请使用它来填充所有数字:

rename 's/(\d+)/sprintf("%03d",$1)/eg' *
Run Code Online (Sandbox Code Playgroud)

s/old/new/是替换操作将取代oldnew。在这里,因为(\d+)是在括号中,所以匹配的任何内容都将被捕获,然后将$1在替换的右侧可用。因此,我们将数字替换为 0 填充(sprintf("%03d", $number)$number用 0 填充,直到其长度为 3)。最后,该标志e让我们可以使用表达式(此处为sprintfg并使替换成为全局的,对于输入行(文件名)上的所有匹配项。

请注意,如果您的数字已经用超过 3 个 0 填充 0,这会将其修剪为 3-0 填充。所以file 00000001.mp3会变成file 001.mp3.


Sté*_*las 6

zsh

autoload -Uz zmv # best in ~/.zshrc
zmv -n '(*).mp4' '${1//(#m)<->/${(l[3][0])MATCH}}.mp4'
Run Code Online (Sandbox Code Playgroud)

-n如果满意,请删除(试运行)。

  • zmv根据 zsh glob 模式重命名文件。这里(*).mp4匹配以 结尾的文件名,.mp4前面的部分.mp4捕获,因此它可以$1在替换中使用。
  • ${1//pattern/replacement}: ksh 运算符对参数(此处$1)扩展执行替换。
  • 这里pattern(#m)<->zshextendedglob模式。(#m)使匹配的文本$MATCH在替换中可用<->,最简单的<x-y>数字匹配运算符形式匹配 1 个或多个十进制数字的任何序列。一样[0-9]##
  • ${(l[3][0])param}使用l[length][padstring]参数扩展标志将$MATCH0的扩展左填充到长度 3(注意它也会将数字截断到长度 3)。

避免截断是可能的,尽管它变得有点复杂:

zmv -n '(*).mp4' '${1//(#m)<->/${(l[$#MATCH > 3 ? $#MATCH : 3][0])MATCH}}.mp4'
Run Code Online (Sandbox Code Playgroud)

不是填充+截断到长度 3,我们填充+截断到长度是 3 的最大值和要填充的字符串的长度。或者,您可以使用max()autoloadablezmathfunc函数中的数学函数:

autoload -Uz zmv zmathfunc; zmathfunc
zmv -n '(*).mp4' '${1//(#m)<->/${(l[max(3, $#MATCH)][0])MATCH}}.mp4'
Run Code Online (Sandbox Code Playgroud)