如何重命名与父文件夹同名的文件

如何重命名与父文件夹同名的文件

我有一个名为movieson 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包中。它也可以被调用为prenamefile-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

相关内容