Переименование файлов и каталогов рекурсивно в ubuntu / bash

Я хочу переименовать все файлы и каталоги, содержащие слово "special" в "regular". Он должен поддерживать чувствительность к регистру, чтобы "Специальный "не стал"регулярным".

Как я могу сделать это в bash рекурсивно?

5 ответов


попробуйте сделать это (require bash --version >= 4):

shopt -s globstar
rename -n 's/special/regular/' **

удалить -n переключатель, когда ваши тесты в порядке

warningесть другие инструменты с тем же именем, которые могут или не могут это сделать, поэтому будьте осторожны.

если вы выполните следующую команду (GNU)

$ file "$(readlink -f "$(type -p rename)")"

и у вас есть результат как

.../rename: Perl script, ASCII text executable

и не содержащие:

ELF

затем эта кажется, это правильный инструмент =)

если нет, чтобы сделать его по умолчанию (обычно уже) на Debian и производные, такие как Ubuntu :

$ sudo update-alternatives --set rename /path/to/rename

(вместо /path/to/rename в путь .


если у вас нет этой команды, найдите диспетчер пакетов, чтобы установить его или сделать это вручную


и последнее, но не менее важное: этот инструмент был первоначально написан Ларри Уоллом, отцом Perl.


решение с использованием find:

переименовать только файлы:

find /your/target/path/ -type f -exec rename 's/special/regular/' '{}' \;

переименовать каталоги только:

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \+

переименовать как файлы и каталоги:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+

Если вы не против установки другого инструмента, то вы можете использовать rnm:

rnm -rs '/special/regular/g' -dp -1 *

Он будет проходить через все каталоги/подкаталоги (из-за -dp -1) и заменить специальные С обычный в их имена.


@speakr это был для меня ключом.

если вы используете-execdir для преобразования файлов и каталогов, вы также захотите удалить -type f из приведенного примера. Чтобы разобрать его, используйте:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+

кроме того, подумайте о добавлении g (глобальный) флаг в regex, если вы хотите заменить все возникновения special С regular в данном имени файла, а не только в первом вхождении. Для пример:

find /your/target/path/ -execdir rename 's/special/regular/g' '{}' \+

превратят special-special.jpg to regular-regular.jpg. Без глобального флага вы получите regular-special.jpg.

FYI: GNU Rename не установлен по умолчанию на Mac OSX. Если вы используете менеджер пакетов Homebrew, brew install rename исправит это.


для тех, кто просто хочет переименовать каталоги, вы можете использовать эту команду:

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

Примечание тип теперь d для каталога, и с помощью -execdir.

Я не смог понять, как переименовать файлы и каталоги за один проход.

кто-то ранее прокомментировал, что после переименования корневой папки он больше не может пересекать дерево файлов. Есть -d переключатель доступный который делает траверсал глубины от снизу вверх, поэтому корень будет переименован последним, я считаю:

find -d /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

из manpage (man find):

 -d      Cause find to perform a depth-first traversal, i.e., directories are visited in post-order and all entries in a directory will be
         acted on before the directory itself.  By default, find visits directories in pre-order, i.e., before their contents.  Note, the
         default is not a breadth-first traversal.