Bash переименовать 360 000 файлов с помощью find -exec

Bash переименовать 360 000 файлов с помощью find -exec

У меня около 360 000 файлов, таких как:

./001/1/1.jpg
./001/1/2.jpg
./001/2/1.jpg
./002/1/1.jpg
./003/1/1.jpg
...
pattern: [60 dirs]/[1000 subdirs]/[4-10 files].jpg

Я хочу переименовать файлы, renameнапример, из *.jpg в *.jpeg. Я не могу сделать это с помощью single rename, потому что получаю ошибку argument list is too long.

В поисках решения я нашел вот это, но оно ничего не переименовывает:

find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's/jpg/jpeg/' {}/* \;

Когда я проверяю, {}развернуто ли, заменяя rename на echo:

find -maxdepth 2 -mindepth 2 -type d -exec echo "rename -n 's/jpg/jpeg/' {}/*" \;

Я получаю ожидаемый результат:

rename -n 's/jpg/jpeg/' ./061/61430/*
rename -n 's/jpg/jpeg/' ./061/61431/*
...

Если я запускаю любую из этих команд переименования, то переименование работает. Так что проблема должна быть в {}.

Спасибо за помощь!

решение1

В первом случае, *раскрывается оболочкой до того, как доберется до rename(если он вообще раскрывается — сомневаюсь, что что-то совпадает {}/*), а если не раскрывается, то выполняется команда renameс тремя аргументами -n, s/jpg/jpeg/и some/path/*. Последний аргумент не является именем существующего файла, поэтому renameничего не делает.

Без подстановки оболочки путь бесполезен rename.

Поэтому вместо этого сделайте следующее:

find -maxdepth 3 -mindepth 3 -type f -iname '*.jpg' -exec rename -n 's/jpg$/jpeg/i' {} +

Используйте findвозможность строить командные строки как можно длиннее +вместо ;.

решение2

find  | prename 's/\.jpg$/.jpeg/'

или если у вас есть другие файлы в текущем каталоге

find 0[0-9][0-9] | prename 's/\.jpg$/.jpeg/'

решение3

Не следует указывать type d, если вы не хотите переименовывать только каталоги. Чтобы изменить расширения , .jpgпопробуйте.jpeg

find . -maxdepth 2 -mindepth 2 -name '*.jpg' -exec sh -c 'echo mv -- "$0" "${0%%.jpg}.jpeg"' {} \;

Удалите, echoесли вам нравится то, что вы видите на экране.

решение4

Используя cygwin, моя версия rename не имеет замены regex, и ее rename [options] expression replacement file...синтаксис, похоже, не работает. Кроме того, предложения bash терпят неудачу с

... -c: line 0: unexpected EOF while looking for matching `"'
... -c: line 1: syntax error: unexpected end of file

Увы... всегда есть perl:

perl -MFile::Find -e 'find(sub{return unless /^(.*)\.jpg$/;`mv $_ $1.jpeg`}, ".")'

Связанный контент