Изменение имени файла с нижнего регистра на верхний регистр рекурсивно

У меня есть 1 000 000 файлов в некоторых папках и подпапках. Я хочу переименовать их из нижнего регистра в верхний регистр, используя команды оболочки. Я не хочу изменять расширение. только часть имени файла.

Я нашел это:

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

но он не рекурсивный и работает только с файлами в текущей папке.

Затем я попробовал это:

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

Но файлы не изменились.

Как я могу использовать его рекурсивно?

Предполагая, что у вас есть переименование Perl, предоставленное Debian и производными дистрибутивами, такими как Debian и Ubuntu, вы почти там. Проблема в том, что -execdir передает имя файла с префиксом ./ к команде. (Причина в том, что некоторые команды относятся к аргументам, начинающимся с некоторых символов специально, таким образом, если у вас есть файл с именем -foo , он передается как ./-foo и поэтому рассматривается как файл, а не как опция.) С ваше регулярное выражение, это приводит к тому, что $1 всегда пуст, и, следовательно, новое имя совпадает со старым именем.

Подойдите к этому. ./ В своем регулярном выражении.

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

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

Вы можете использовать этот маленький скрипт 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 mv "$1" "${dn}/${newfn}" ' _ {} \; 
 ls -r | rename 's/^([^.]*)\.(.*)$/\U$1\E.$2/' 

Это нормально?