我必须递归地重命名一个完整的文件夹树,这样就不会出现大写字母(这是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.


当前回答

for f in `find -depth`; do mv ${f} ${f,,} ; done

Find -depth打印每个文件和目录,目录的内容在目录本身之前打印。${f,,}将文件名小写。

其他回答

在这种情况下,我会使用Python,以避免乐观地假设没有空格或斜杠的路径。我还发现python2往往被安装在更多的地方,而不是重命名。

#!/usr/bin/env python2
import sys, os

def rename_dir(directory):
  print('DEBUG: rename('+directory+')')

  # Rename current directory if needed
  os.rename(directory, directory.lower())
  directory = directory.lower()

  # Rename children
  for fn in os.listdir(directory):
    path = os.path.join(directory, fn)
    os.rename(path, path.lower())
    path = path.lower()

    # Rename children within, if this child is a directory
    if os.path.isdir(path):
        rename_dir(path)

# Run program, using the first argument passed to this Python script as the name of the folder
rename_dir(sys.argv[1])
( find YOURDIR -type d | sort -r;
  find yourdir -type f ) |
grep -v /CVS | grep -v /SVN |
while read f; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done

首先自底向上重命名目录sort -r(其中-depth不可用),然后是文件。 然后grep -v /CVS而不是find…-修剪,因为这样更简单。 对于大目录,对于f在…可以溢出一些shell缓冲区。 使用find…|在读取时避免这种情况。

是的,这将打击只有在情况下不同的文件…

使用排版:

typeset -l new        # Always lowercase
find $topPoint |      # Not using xargs to make this more readable
  while read old
  do new="$old"       # $new is a lowercase version of $old
     mv "$old" "$new" # Quotes for those annoying embedded spaces
  done

在Windows上,像Git Bash这样的模拟可能会失败,因为Windows在本质上不区分大小写。对于这些,添加一个步骤,mv的文件首先到另一个名称,如“$old.tmp”,然后到$new。

使用Larry Wall的文件名修复器:

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

这很简单

find | fix 'tr/A-Z/a-z/'

(其中fix当然是上面的脚本)

如果你不需要关心效率,就试试下面的方法。

zip -r foo.zip foo/*
unzip -LL foo.zip