Рекурсивно перейменувати файли (розширення змін) в Linux


23

Як перейменувати всі файли в каталозі, рекурсивно, змінюючи одне розширення файлу на інше, для тисяч файлів у тисячах підпапок? Я бачу багато команд, які виконують майже те, що я хочу, але не зовсім.

find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."

...

rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile

1
У вас є Debian renameчи Red Hat rename?
Ігнасіо Васкес-Абрамс

@Ignacio: Ubuntu = Debian?
ендоліт

Так, Ubuntu є похідною Debian.
Ігнасіо Васкес-Абрамс

Відповіді:


24

Зрозумів це

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile

звичайно, видаліть -v, коли насправді це робите, інакше це витратить час на відображення всіх файлів


14

Щось на зразок:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

це найкраще працювало для мене
cwd


4

Я знайшов цей метод легше і легше читати:

find . -name "*.andnav" | rename "s/\.andnav$/.tile/"

Принаймні, для перейменування Ubuntu перейменування приймає список файлів з STDIN, якщо жоден не знаходиться в командному рядку. І це можна легко перевірити за допомогою:

find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/"

поки ви не зрозумієте це правильно.


1

Перейменуйте файли та каталоги за допомогою find -execdir | rename

Якщо ви збираєтесь перейменовувати і файли, і каталоги не просто із суфіксом, це хороший зразок:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find . -depth -execdir rename 's/findme/replaceme/' '{}' \;

Дивовижна -execdirопція робить cdв каталог перед виконанням renameкоманди, на відміну від -exec.

-depth переконайтеся, що перейменування відбувається спочатку на дітей, а потім на батьків, щоб запобігти можливим проблемам із відсутніми батьківськими каталогами.

-execdir Потрібно, оскільки перейменування не спрацьовує добре з вхідними контурами без базової назви, наприклад, такими помилками:

rename 's/findme/replaceme/g' acc/acc

PATHХакерство потрібно , тому що -execdirмає один дуже прикрий недолік: findвкрай самовпевнений і відмовляється що - небудь робити з , -execdirякщо у вас є якісь - або відносні шляхи в вашому PATHзмінному оточенні, наприклад ./node_modules/.bin, в іншому випадку з:

find: Відносний шлях './node_modules/.bin' включений в змінну середовища PATH, яка є небезпечною у поєднанні з дією -execdir пошуку. Видаліть цей запис із $ PATH

Дивіться також: /ubuntu/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdirє розширенням пошуку GNU до POSIX . renameзаснована на Perl та постачається з renameпакету. Тестовано в Ubuntu 18.10.

Перейменуйте спосіб пошуку

Якщо ваші вхідні шляхи не надходять find, або якщо у вас достатньо відносного роздратування шляху, ми можемо скористатись певним пошуковим кодом Perl для безпечного перейменування каталогів, як у:

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

Я не знайшов зручний аналог для -execdirз xargs: Xargs: зміна робочого каталогу шлях до файлу перед виконанням?

sort -rПотрібно для того , щоб файли приходять після їх відповідних каталогів, так як більш довгі шляхи приходять після того, як більш короткі, з тим же префіксом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.