我有一个名为movies
on my Ubuntu 的文件夹,其中包含许多子文件夹。
每个子文件夹包含 1 个 mp4 文件,并且可能包含其他文件(jpg、srt)。
每个子文件夹具有相同的标题格式:
My Subfolder 1 (2001) Bla Bla
My Subfolder 2 (2000) Bla
My Subfolder 3 (1999)
如何将 mp4 文件重命名为与父文件夹相同但不包含年份和 blabla?
例如,上面子文件夹内的 mp4 变为:
My Subfolder 1.mp4
My Subfolder 2.mp4
My Subfolder 3.mp4
我希望 mp4 保留在其子文件夹中,只是名称会更改。年份始终位于括号中。
答案1
这是一个 bash 解决方案:
cd movies
for mp4 in */*.mp4
do
if [[ $mp4 =~ ^(.*)\ \( ]]
then
echo mv -- "$mp4" ...to... "${mp4%%/*}/${BASH_REMATCH[1]}".mp4
fi
done
这会循环遍历“movies”每个子目录中的每个 mp4 文件,并对其应用模式匹配测试。如果匹配:
^
- 从一开始就(.*)
- 捕获任意数量的角色并将其保存下来\ \(
- 后面跟着一个空格和一个左括号
如果匹配成功,那么我们就在目录中找到了一个具有您期望的模式的 mp4 文件。 Bash 将带括号的匹配项保存在$BASH_REMATCH
数组变量中,因此我们(将)mv
使用原始文件名和拼凑而成的新名称进行调用:
${mp4%%/*}
是原来的目录名/
/ - 目录分隔符${BASH_REMATCH[1]}".mp4
- 上面保存的部分,后缀为.mp4
如果结果看起来正确,请删除echo
和...to...
部分。
答案2
使用perl
重命名实用程序:
rename 's/\(\d\d\d\d\)//' */*.mp4
如果您想要试运行看看它会做什么,请使用-n
(又名--nono
)选项:
rename -n 's/\(\d\d\d\d\)//' */*.mp4
在 Debian(和 Ubuntu 等)上,基于 perl 的重命名位于file-rename
包中。它也可以被调用为prename
或file-rename
。
顺便说一句,这个版本的重命名的一个非常有用的功能是,虽然它很容易对文件名进行sed
样式tr
转换,但您实际上可以使用任何修改后的 Perl 代码$_
来重命名文件,甚至包括复杂的脚本。
从手册页:
rename
根据第一个参数指定的规则重命名提供的文件名。参数perlexpr
是一个 Perl 表达式,预计$_
至少会修改某些指定文件名的 Perl 字符串。如果给定的文件名未被表达式修改,则不会重命名。如果命令行上没有给出文件名,则将通过标准输入读取文件名。例如,要重命名所有匹配“*.bak”的文件以去除扩展名,您可能会说
rename 's/\.bak$//' *.bak
要将大写名称转换为小写名称,您可以使用
rename 'y/A-Z/a-z/' *
请注意,还有其他版本的rename
具有完全不同的命令行选项和参数,包括util-linux
包中的一个(通常名为/usr/bin/rename.ul
)。在使用之前验证rename
您安装的版本非常重要 - 或者更准确地说,调用或符号链接到哪个版本/usr/bin/rename
在 Debian 和 Ubuntu 及相关系统上,您可以检查update-alternatives
:
# update-alternatives --display rename
rename - auto mode
link best version is /usr/bin/file-rename
link currently points to /usr/bin/file-rename
link rename is /usr/bin/rename
slave rename.1.gz is /usr/share/man/man1/rename.1.gz
/usr/bin/file-rename - priority 70
slave rename.1.gz: /usr/share/man/man1/file-rename.1p.gz