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
或任何您喜欢的外壳。
ABCdef
,abcDEF
和aBcDeF
?重命名脚本应该中止还是只是警告并继续?2.如何为非US-ASCII名称定义小写?如果可能出现这样的名称,是否应该首先执行一次检查并排除通过?3.如果您正在运行重命名操作