我必须递归地重命名一个完整的文件夹树,这样就不会出现大写字母(这是c++源代码,但这无关紧要)。

忽略CVS和Subversion版本控制文件/文件夹的加分项。首选的方法是shell脚本,因为shell应该在任何Linux机器上可用。

关于文件重命名的细节有一些有效的争论。

I think files with the same lowercase names should be overwritten; it's the user's problem. When checked out on a case-ignoring file system, it would overwrite the first one with the latter, too. I would consider A-Z characters and transform them to a-z, everything else is just calling for problems (at least with source code). The script would be needed to run a build on a Linux system, so I think changes to CVS or Subversion version control files should be omitted. After all, it's just a scratch checkout. Maybe an "export" is more appropriate.


当前回答

我在Mac OS X上发现的最简单的方法是使用http://plasmasturm.org/code/rename/:上的重命名包

brew install rename
rename --force --lower-case --nows *

——force即使目标文件名已经存在,也要重命名。 ——lower-case将文件名全部转换为小写。 替换文件名中所有空格序列为单个下划线字符。

其他回答

上面的大多数答案都很危险,因为它们不处理包含奇数字符的名称。对于这种情况,最安全的方法是使用find的-print0选项,该选项将以ASCII NUL而不是\n终止文件名。

下面是一个脚本,它只改变文件而不改变目录名,以免混淆find:

find .  -type f -print0 | xargs -0n 1 bash -c \
's=$(dirname "$0")/$(basename "$0");
d=$(dirname "$0")/$(basename "$0"|tr "[A-Z]" "[a-z]"); mv -f "$s" "$d"'

我对它进行了测试,它适用于包含空格、各种引号等的文件名。这很重要,因为如果您以根用户身份运行树中的其他脚本,其中包括由

touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

... 你猜怎么着……

这是一个小的shell脚本,做你所要求的:

root_directory="${1?-please specify parent directory}"
do_it () {
    awk '{ lc= tolower($0); if (lc != $0) print "mv \""  $0 "\" \"" lc "\"" }' | sh
}
# first the folders
find "$root_directory" -depth -type d | do_it
find "$root_directory" ! -type d | do_it

注意第一个find中的-depth动作。

不能移植,只能使用Zsh,但是非常简洁。

首先,确保加载zmv。

autoload -U zmv

同时,确保extendedglob是打开的:

setopt extendedglob

然后使用:

zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'

递归到名称不是CVS的小写文件和目录。

我相信这些一行代码可以简化为:

对于f在**/*;做mv "$f" "${f:l}";完成

我在Mac OS X上发现的最简单的方法是使用http://plasmasturm.org/code/rename/:上的重命名包

brew install rename
rename --force --lower-case --nows *

——force即使目标文件名已经存在,也要重命名。 ——lower-case将文件名全部转换为小写。 替换文件名中所有空格序列为单个下划线字符。