我正在使用脚本来备份文件,并避免覆盖我使用过的文件cp --backup
。这给我留下了许多看起来像example.mov.orig
和 的文件test.mov.orig
。我根本无法弄清楚正则表达式,并且想知道是否有人知道如何使用重命名来切断.orig
并附加到_1
基本名称。
本质上,我正在寻找的结果是命令,该命令将更改为example.mov.orig
我example_1.mov
可以结合使用find /example/ -name *.*.orig
输出rename --version
是util-linux-ng 2.18
答案1
您需要的命令rename
是:
如果您使用的
rename
是util-linux
:rename . _1. *.orig && rename .orig '' *.orig
对于所有以 . 结尾的文件,第一个将替换第一次出现
.
的.第二个将从文件名中删除。_1.
.orig
.orig
如果您使用 perl-rename (基于 Debian 的系统上的默认设置),事情会更简单,因为它使用 Perl 兼容的正则表达式,因此可以一步完成所有操作:
rename 's/(\..*)\.orig/_1$1/' *orig
由于此版本使用 正则表达式 将匹配第一个
.
(\.
,.
需要转义,因为 ti 表示未转义的“任何字符”),然后是所有内容 (.*
) 直到.orig
。由于第一个模式位于括号内,因此它被“捕获”并且以后可以称为$1
。因此,替换将替换之前与 a_1
和捕获的模式(第一个扩展名)匹配的任何内容,并且同时删除.orig
.
您可以将命令与find
如下组合:
find /example -name '*.orig' -exec rename . _1. {} +
find /example -name '*.orig' -exec rename .orig '' {} +
或者:
find /example -name '*.orig' -exec rename 's/(\..*)\.orig/_1$1/'
你甚至不需要find
这个。如果所有文件都位于同一目录中,则可以直接使用上面的命令,或者使其递归(假设您使用的是 bash):
shopt -s globstar ## make ** recurse into subdirectories
rename.ul . _1. **.orig && rename.ul .orig '' **.orig ## util-linux
rename 's/(\..*)\.orig/_1$1/' **orig ## perl rename
事实上,严格来说,你甚至不需要rename
。您可以在 shell 中执行所有操作(请参阅这里有关 shell 字符串操作能力的说明):
for file in **/*.orig; do
newname="${file%%.*}_1.${file#*.}"
mv "$file" "${newname/.orig/}"
done
最后,关于 glob 的注释(-name
使用 glob,而不是正则表达式)。*.*.orig
Windows 的 glob 语法表示“以 结尾的任何内容.orig
”。 等效于 以及您应该与 一起使用的find
是*.orig
。*
单独使用 可以匹配任何内容,使用*.*.orig
只会匹配具有两个扩展名的文件名,其中最后一个是.orig
。
答案2
首先你应该检查你的系统中安装了哪个版本的rename
readlink -e $(which rename)
因此对于prename
(.deb 主机中的默认值):
prename 's/(\.[^.]*)\.orig/_1$1/' *.*.orig
以及rename.ul
来自 util-linux 包的
rename.ul \. _1\. *.*.orig #add «_1» into file name
rename.ul \.orig '' *.*.orig #remove «.orig» extention