find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh
Я не пробовал более сложные сценарии, упомянутые здесь, но ни одна из версий для командной строки не работала для меня на моем Synology NAS. rename
недоступен, и многие из вариантов find
терпят неудачу, потому что кажется, что он придерживается более старого имени уже переименованного пути (например, если он находит ./FOO
с последующим ./FOO/BAR
, переименовывая ./FOO
до ./foo
будет по-прежнему перечислять ./FOO/BAR
, даже если этот путь больше не действителен). Выше команда работала для меня без каких-либо проблем.
Ниже приводится объяснение каждой части команды:
find . -depth -name '*[A-Z]*'
При этом будет найден любой файл из текущего каталога (измените .
на любой каталог, который вы хотите обработать), используя поиск в глубину (например, он выведет список ./foo/bar
перед ./foo
), но только для файлов, которые содержат заглавные буквы. Фильтр -name
применяется только к базовому имени файла, а не к полному пути. Так что это будет список ./FOO/BAR
, но не ./FOO/bar
. Это нормально, так как мы не хотим переименовывать ./FOO/bar
. Мы хотим переименовать ./FOO
, но это будет упомянуто позже (вот почему -depth
важно).
Эта команда сама по себе особенно полезна для поиска файлов, которые вы хотите переименовать. Используйте это после полной команды переименования для поиска файлов, которые все еще не были заменены из-за конфликтов имен файлов или ошибок.
sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'
Эта часть читает файлы, выведенные find
, и форматирует их в команде mv
с использованием регулярного выражения. Опция -n
останавливает sed
от печати ввода, а команда p
в регулярном выражении поиска и замены выводит замененный текст.
Само регулярное выражение состоит из двух захватов: части до последнего / (которая является каталогом файла) и самого имени файла. Каталог остается без изменений, но имя файла преобразуется в нижний регистр. Таким образом, если find
выведет ./FOO/BAR
, оно станет mv -n -v -T ./FOO/BAR ./FOO/bar
. Опция -n
mv
гарантирует, что существующие строчные файлы не будут перезаписаны. Опция -v
заставляет mv
выводить каждое внесенное изменение (или не вносить - если ./FOO/bar
уже существует, выводится что-то вроде ./FOO/BAR -> ./FOO/BAR
, отмечая, что никаких изменений не было сделано). -T
очень важен здесь - он рассматривает целевой файл как каталог. Это гарантирует, что ./FOO/BAR
не будет перемещен в ./FOO/bar
, если этот каталог существует.
Используйте это вместе с find
, чтобы сгенерировать список команд, которые будут выполняться (удобно для проверки того, что будет сделано, без фактического выполнения)
sh
Это довольно очевидно. Он направляет все сгенерированные команды mv
в интерпретатор оболочки. Вы можете заменить его на bash
или любую другую оболочку по своему вкусу.