从 TitleCase -> Title Case 批量重命名文件(空格分隔)

从 TitleCase -> Title Case 批量重命名文件(空格分隔)

我有一个 38GB 的​​文件夹,里面有 800 个 MP4 视频。重新下载后,文件名变成了无间距,所有单词都连接起来,但仍然是 TitleCase。

所以从TitleCase我需要Title Case

批量重命名这些文件的最有效方法是什么?

我记得很久以前我的发行版中就包含了rename或,但现在似乎没有了。autorename

答案1

如果要在 mp4 文件名 TitleCase 的每个“单词”之间添加空格(PascalCase 到以空格分隔的单词):

rename -n 's/\B[[:upper:]]/ $&/g' ./*.mp4

输出

rename(./FooBarBaz.mp4, ./Foo Bar Baz.mp4)

查看这篇文章,其中深入详细介绍了 Perlrename

重命名不同的版本和用法怎么样?特别推荐使用 Perl 版本的方式是什么?

答案2

我不知道什么是最有效的方法(我认为你的意思是有效),但我会快速编写一个 for 循环,例如:

for file in *.mp4; do
  newname="$(echo "$file" | sed 's/\(.\)\([A-Z]\)/\1 \2/g')"
  mv "${file}" "${newname}"
done

解释:

  newname="$(echo "$file" | sed 's/\(.\)\([A-Z]\)/\1 \2/g')"
#        ^-------------------- Assign to  variable "newname" value…
#         ^------------------- "$()": as output by commannd in parentheses;
#                              use "" to avoid word splitting

在哪里

echo $file | sed 's/\(.\)\([A-Z]\)/\1 \2/g'
#    ^-------------------------------------- output old file name
#          ^-------------------------------- pipe to `sed` command

sed是“流编辑器”的名称;它接受输入,对其执行命令,并产生输出。这里的命令是s,如“搜索和替换”中所示。

s/\(.\)\([A-Z]\)/\1 \2/g
^^ ^  ^ ^      ^ ^  ^  ^
|| |^ | | ^^^  | |  |  |
\------------------------ s: search and replace
 \----------------------- /: Set the search;replace;flags separator to "/"
   || | | \|/  | \  /  |
   \--+------------------ \(…\): a "capture group" (the first one);
    |   |  |   |  ||   |         whatever is matches the content will be
    |   |  |   |  \|   |         available as \1
    \-------------------- .: We match ".", which means *any* character
        |  |   |   |   |  (which precludes this from matching at start of line)
        \------+--------- \(…\): Second capture group, \2
           \------------- [A-Z]: Match any capital letter
                   |   |
                   \----- Replacement: "\1 \2" replace
                       |  "characterbeforecapitalletter""Capitalletter" with
                       |  "characterbeforecapitalletter" "Capitalletter"
                       |
                       \- g: Flag that means "global": Repeat this until
                             end of line

答案3

要分隔标题大小写中的单词,例如 to FooBarBaz.mp4be Foo Bar Baz.mp4,您可以在每个大写字母之前插入一个空格,除非它是文件名中的第一个字符,使用 zshzmv可以(递归地)执行以下操作:

$ autoload -Uz zmv
$ zmv -n '(**/)(?)(*.mp4)' '$1$2${3//(#m)[[:upper:]]/ $MATCH}'
mv -- FooBarBaz.mp4 'Foo Bar Baz.mp4'
mv -- OnceUponATime.mp4 'Once Upon A Time.mp4'

-n如果愿意,请删除以进行空运行)。

当心它会Foo-Bar.mp4变成Foo- Bar.mp4.

zmv -n '(**/)(*.mp4)' '$1${2//(#b)([[:alpha:]])([[:upper:]])/$match[1] $match[2]}'

只会在字母和大写字母之间插入空格,但不适用于OnceUponATime上面,因为空格将插入到nand之间A,而不是插入到A和之间,T因为A已经是消耗的通过之前的替换。

由于 zsh glob 没有与 perl 的环视操作符相当的功能,因此解决这个问题更加困难。在这种情况下,一个简单的方法是额外重复一次替换:

$ zmv -n '(**/)(*.mp4)' '$1${${2//(#b)([[:alpha:]])([[:upper:]])/$match[1] $match[2]}//(#b)([[:alpha:]])([[:upper:]])/$match[1] $match[2]}'
mv -- ABCDEF.mp4 'A B C D E F.mp4'
mv -- AChristmasCarol.mp4 'A Christmas Carol.mp4'
mv -- FooBarBaz.mp4 'Foo Bar Baz.mp4'
mv -- LeSongeD\'UneNuitD\'Été.mp4 'Le Songe D'\''Une Nuit D'\'Été.mp4
mv -- LifeOfΠ.mp4 'Life Of Π.mp4'
mv -- OnceUponATime.mp4 'Once Upon A Time.mp4'

答案4

其他答案描述了允许基于正则表达式进行更改的工具,这是一个很好的方法。然而,这些答案并没有解决一个重要的问题(恕我直言):在磁盘上实际进行更改之前预览功能(这可能很难逆转)。

输入 Emacs 及其dired模式,特别是wdired,记录在手动的。可以打开包含文件的目录的 dired,切换 wdired 以使文件名可编辑,进行更改 - 最有可能使用交互式正则表达式搜索和替换,查看更改,最后将它们提交到磁盘。

我知道为这个用例安装 Emacs 是一种严厉的方法,但我要指出的是,它可以轻松地处理带有困难字符(例如空格)的文件名。

相关内容