我有一组文件,命名如下:
048. banana.mkv
049. apple.mkv
050. mango.mkv
051. pear.mkv
052. grape.mkv
我需要使用以下命名约定重命名这些文件
01. banana.mkv
02. apple.mkv
03. mango.mkv
04. pear.mkv
05. grape.mkv
问题是我需要重命名数百个文件以及需要从多个组开始01
和增加。通常我rename
用来批量重命名文件。在这种情况下,我一直使用qvm
to 来更改每个文件名。当然有更简单的方法。
使用基于 perl 的
rename
实用程序:这里的技巧是替换
e
修饰符s/pattern/replacement/
- 它允许您将替换字符串评估为 perl 表达式 - 包括算术$1-47
和填充格式通过sprintf
.-n
当您对它正在做正确的事情感到满意时,请删除它。如果你只有一个外壳,那么:
echo
一旦你很高兴它在做正确的事情,就删除它。zsh
和_zmv
在这种情况下,数字格式是使用
l
(字母 ell)扩展修饰符 - from完成的man zshexpn
:与 一样
rename
,删除-n
以实际更改名称。我认为起始编号不一定总是
048
,在这种情况下,您可能需要一个可以在每个目录中运行的命令——无需修改——并且总是做正确的事情。您可以在每个目录中运行它:
这类似于Steeldriver 的答案,主要区别在于它会为您确定从哪里开始。还有其他细微差别。请注意,如果输入编号中存在空白,这将填补输出编号中的空白,这可能是也可能不是您想要的。也就是说,如果您的文件是
048. banana.mkv
、049. apple.mkv
和051. mango.mkv
,则输出将是01. banana.mkv
、02. apple.mkv
和03. mango.mkv
(不是04. mango.mkv
)。-n
如所写,由于该选项,该命令不会重命名任何文件。相反,它显示了它会做什么。如果您对此感到满意,您可以再次运行它而无需-n
:你可能没有这个
file-rename
命令。如果你不这样做,那么你很可能没有rename
命令,或者(这就是我建议使用file-rename
over的原因rename
)你的rename
命令可能完全不同。如果您没有file-rename
(或者如果您更喜欢将其写成rename
并且没有),您可以通过安装rename
包来获得它:这个怎么运作
当您的 shell 将 glob 模式(例如
*.mkv
文件名列表)扩展为文件名列表时,结果列表按字典顺序排列。这究竟意味着什么取决于您当前的语言环境,并且通常它与数字顺序不同,即使两者都适用。但是,由于您的文件名在一开始就编号,并且所有数字都在左侧用0
s 填充,因此不会出现此问题,并且您的 shell 会扩展*.mkv
为按数字顺序排列的路径列表。由于 shell 会处理这个问题,剩下的预防措施是确保
file-rename
避免更改任何不以三个数字序列开头的文件,后跟一个.
.在替换表达式中
s/^\d{3}\./sprintf "%02d.", ++our $i/e
:^\d{3}\.
是一个正则表达式。它与文件名 ( ) 开头的三个 ( ) 数字 ( ) 之后出现的文字.
( ) 匹配。\.
{3}
\d
^
sprintf "%02d.", ++our $i
是 Perl 代码。它使用一个全局变量
$i
,如果还没有看到(our
)就这样引入它。$i
以零值开始,但每次使用时都会增加,在使用之前立即增加(前缀++
这样做)。因此,对于每个文件,它都采用值 1、2、3 等等。sprintf
用于格式化它,如果需要,在左边用零填充,宽度为 2,后跟文字.
. (.
只需要在正则表达式中转义,否则它将匹配任何字符,而不是在用于替换的表达式中。e
最后导致表达式被评估为 Perl 代码以产生替换结果。如果没有 thise
,以 开头的实际文本sprintf
将被替换为每个文件名,而不是将该文本作为 Perl 代码评估的结果。名称不以三个数字开头后跟 a
.
的文件不会被重命名,也不会导致$i
递增。不以后缀结尾的文件名.mkv
甚至不会首先传递给file-rename
。自动化它
您可能只想在每个目录中运行一次,因为听起来您只有少数几个目录。但如果你想自动化它,你可以。这可以用 来完成
find
,尽管它比最初看起来更棘手和复杂,因为路径看起来像从find
(例如,-execdir
你会得到类似的路径./048. banana.mkv
),并且因为-exec
/-execdir
with+
将拆分为多个命令(重置$i
不受欢迎)在非常大的目录(您没有,但这是另一个必须考虑的因素)的情况下。因此,您可能只想使用 shell 循环来运行它:
(这也不适用于具有大量
*.mkv
文件的目录,但它会为这些目录提供错误消息,而不是做错事。)替换
dir1 dir2
为包含要重命名的文件的实际目录列表。这会产生如下输出:
如果看起来不错,您可以
-n
像以前一样删除 。(您仍然会看到目录名称标题,但看不到rename(..., ...)
行。如果您想在实际重命名期间也看到这些标题,您可以将-v
选项传递给file-rename
,即替换-n
为-v
而不是仅仅删除-n
。这可能会使它更难不过要注意任何错误消息。)延伸阅读
在 Ubuntu 中批量重命名文件;重命名命令的最简短介绍(由Oli提供)显示并解释了几种使用方法
rename
,包括使用sprintf
.这适用于当前的 Perl 重命名器
file-rename
和旧的重命名器prename
。(在最新的 Ubuntu 版本中,file-rename
它们prename
是相同的,但在旧版本中它们是不同的并且具有一些不同的行为。)在 Ubunturename
中,默认情况下要么不存在,要么是解析为其中之一的符号链接。它不适用于rename.ul
某些系统上的其他实用程序(如果您将其配置为在 Ubuntu 上执行此操作),则会在您运行rename
.有关 Perl 中正则表达式的信息,我推荐使用
perldoc perlrequick
和perldoc perlre
. 这些涵盖了s/
表达式的语法。有关一般正则表达式的信息,我推荐https://www.regular-expressions.info。