find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh
我没有尝试过这里提到的更复杂的脚本,但没有一个命令行版本适用于我的 Synology NAS。rename
不可用,并且find
失败的许多变体,因为它似乎坚持已重命名路径的旧名称(例如,如果发现./FOO
后跟,即使该路径不再有效./FOO/BAR
,重命名./FOO
为./foo
仍将继续列出) ./FOO/BAR
. 上面的命令对我有用,没有任何问题。
以下是对该命令各部分的解释:
find . -depth -name '*[A-Z]*'
这将使用深度优先搜索(例如,它将在 之前列出)从当前目录中查找任何文件(更改.
为您要处理的任何目录),但仅适用于包含大写字符的文件。过滤器仅适用于基本文件名,而不适用于完整路径。所以这将列出但不是。这没关系,因为我们不想重命名. 虽然我们想重命名,但稍后会列出这个名称(这就是重要的原因)。./foo/bar
./foo
-name
./FOO/BAR
./FOO/bar
./FOO/bar
./FOO
-depth
该命令本身对于首先查找要重命名的文件特别有用。在完整的重命名命令之后使用它来搜索由于文件名冲突或错误而仍未被替换的文件。
sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'
这部分读取输出的文件,并使用正则表达式将find
它们格式化为命令。mv
该-n
选项停止sed
打印输入,并且p
搜索和替换正则表达式中的命令输出替换的文本。
正则表达式本身由两个捕获组成:直到最后一个 / 的部分(这是文件的目录),以及文件名本身。目录保持不变,但文件名被转换为小写。因此,如果find
输出./FOO/BAR
,它将变为mv -n -v -T ./FOO/BAR ./FOO/bar
。-n
选项mv
确保不覆盖现有的小写文件。该-v
选项会mv
输出它所做的每一次更改(或不进行 - 如果./FOO/bar
已经存在,它会输出类似 的内容./FOO/BAR -> ./FOO/BAR
,并注意没有进行任何更改)。这里-T
非常重要 - 它将目标文件视为目录。如果该目录恰好存在,这将确保./FOO/BAR
不会将其移入。./FOO/bar
与它一起使用find
来生成将要执行的命令列表(便于验证将要执行的操作而无需实际执行)
sh
这很不言自明。mv
它将所有生成的命令路由到 shell 解释器。bash
您可以用您喜欢的任何外壳替换它。