递归地将文件名从小写更改为大写

递归地将文件名从小写更改为大写

我的一些文件夹和子文件夹中有 1,000,000 个文件。我想使用 shell 命令将它们从小写重命名为大写。我不想修改扩展名。仅文件名部分。

我找到了这个:

rename 's/^([^.]*)\.(.*)$/\U$1\E.$2/' *

但它不是递归的,仅适用于当前文件夹中的文件。

然后我尝试了这个:

find . -depth  -execdir rename 's/^([^.]*)\.(.*)$/\U$1\E.$2/' {} \;

但没有文件改变。

我怎样才能递归地使用它?

答案1

假设您拥有 Debian 及其派生发行版(例如 Debian 和 Ubuntu)提供的 Perl 重命名,那么您就差不多成功了。问题在于-execdir将前缀为 的文件名传递./给命令。 (原因是某些命令会特殊对待以某些字符开头的参数;这样,如果您有一个名为 的文件-foo,它会作为文件传递./-foo,因此被视为文件而不是选项。)使用正则表达式,这会导致$1始终为空,因此新名称与旧名称相同。

./在正则表达式中适应这一点。

find . -depth  -execdir rename 's/^(\.\/[^.]*)\.(.*)$/\U$1\E.$2/' {} \;

答案2

find . -type f -exec rename -v 's/(\w+).(\w+)$/\U$1\E.$2/' {} \;

答案3

您可以使用这个小 bash 脚本。

#!/bin/bash

find . -type f -exec sh -c  '
    dn=`dirname "$1"`
    bn=`basename "$1"`
    fn=`echo "${bn%.*}"`
    ext=`echo "${bn##*.}"`
    FN=`echo "${fn^^}"`
    newfn="${FN}"."${ext}"
    #echo ${dn}/$newfn
    if [ "${fn}" = "${FN}" ] ;then : ;else echo "${bn} renamed to ${newfn}";mv "$1" "${dn}/${newfn}";fi
' _ {} \;

答案4

ls -r | rename 's/^([^.]*)\.(.*)$/\U$1\E.$2/'

这个可以吗?

相关内容