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


当前回答

使用排版:

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。

其他回答

最初的问题要求忽略SVN和CVS目录,这可以通过在find命令中添加-prune来实现。例如忽略CVS:

find . -name CVS -prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print

[编辑]我尝试了一下,在find中嵌入小写翻译并没有起作用,原因我实际上不明白。因此,将其修改为:

$> cat > tolower
#!/bin/bash
mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'`
^D
$> chmod u+x tolower 
$> find . -name CVS -prune -o -exec tolower '{}'  \;

Ian

我需要在Windows 7上的Cygwin设置上这样做,并发现我在上面尝试的建议中出现了语法错误(尽管我可能错过了一个工作选项)。然而,这个解决方案直接来自Ubuntu论坛:-)

ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done

(注意:我之前用下划线替换了空格:

for f in *\ *; do mv "$f" "${f// /_}"; done

)

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

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

下面是我的次优解决方案,使用Bash shell脚本:

#!/bin/bash
# First, rename all folders
for f in `find . -depth ! -name CVS -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming folder $f"
      mv -f "$f" "$g"
   fi
done

# Now, rename all files
for f in `find . ! -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming file $f"
      mv -f "$f" "$g"
   fi
done

文件夹都正确地重命名,mv在权限不匹配时不会询问问题,CVS文件夹也不会重命名(不幸的是,该文件夹内的CVS控制文件仍然会重命名)。

由于“find -depth”和“find | sort -r”都以可用于重命名的顺序返回文件夹列表,我更喜欢使用“-depth”来搜索文件夹。

MacOS,

安装重命名包,

brew install rename

Use,

find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"                       

该命令查找所有扩展名为*.py的文件,并将文件名转换为小写。

`f` - forces a rename

例如,

$ find . -iname "*.py" -type f
./sample/Sample_File.py
./sample_file.py
$ find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"
$ find . -iname "*.py" -type f
./sample/sample_file.py
./sample_file.py