我的一些文件夹和子文件夹中有 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/'
这个可以吗?