早晨,
我当前正在从事的项目有一个令我困扰的先前的命名方案......
Base.v2.c
Base.v2a.c
Slider.v4a.h
Area.v2a.2.h
有人告诉我,版本中的“a”是为了标识需要更多工作的“alpha”版本。在项目的这个阶段,我可以删除“a”并将其替换为“.1”(v2a -> v2.1)。
文件太多了,超出了我愿意手动处理的范围。
我知道我可以使用 rename 命令一次性重命名所有文件,但我遇到了如何执行此操作的问题。如果我使用类似以下内容的命令:
rename 's/[0-9]a/.1/' *
那么我将丢失版本号的最后一位数字。有没有办法让重命名(或其他命令行工具)记住用于查找文件的正则表达式的一部分?因此,将 '[0-9]a' 更改为 '[0-9].1' 会将 1a 更改为 1.1,将 4a 更改为 4.1,等等。
答案1
您可以使用捕获组:
$ rename -n 's/(\d)a/$1.1/' *
Area.v2a.2.h -> Area.v2.1.2.h
Base.v2a.c -> Base.v2.1.c
Slider.v4a.h -> Slider.v4.1.h
或者你可以使用向后看:
$ rename -n 's/(?<=\d)a/.1/' *
Area.v2a.2.h -> Area.v2.1.2.h
Base.v2a.c -> Base.v2.1.c
Slider.v4a.h -> Slider.v4.1.h
或者,类似于后视,0 长度断言\K
,表示“忘记到此时为止匹配的所有内容”:
$ rename -n 's/\d\Ka/.1/' *
Area.v2a.2.h -> Area.v2.1.2.h
Base.v2a.c -> Base.v2.1.c
Slider.v4a.h -> Slider.v4.1.h
请注意,我使用了较短的\d
而不是[0-9]
。 这两个是等效的,但是rename
是一个 perl 脚本,因此可以理解 Perl 兼容正则表达式 (PCRE) 的语法。
请注意,这只会改变第一次发生一个数字,后面跟着一个a
。这可能是也可能不是您需要的,具体取决于您的文件名。
这些-n
makesrename
显示了它会做什么,但实际上并没有做任何事情。一旦您确认它按预期工作,请将其删除以实际更改文件名。
答案2
修改命令如下:
rename 's/([0-9])a/$1.1/' *
- 替换命令
s/<souce>/<replacement>/
将用替换字符串替换源字符串(可以是正则表达式)。 - 捕获组 - 源字符串中用括号括起来的部分:
(regexp)
,,(string)
等等,将被分配为连续变量的值:$1
,,$2
等等。 - 因此,在替换字符串中,变量
$1
将及其值进行扩展,在这种情况下必须与正则表达式匹配[0-9]
。