рекурсивно добавить расширение файла ко всем файлам

У меня есть несколько каталогов и подкаталогов, содержащих файлы без расширения. Я хочу добавить .jpg ко всем файлам, содержащимся в этих каталогах. Я видел сценарии bash для изменения расширения файла, но не просто для его добавления. Он также должен быть рекурсивным, может кто-нибудь помочь?


person robjmills    schedule 10.07.2009    source источник


Ответы (6)


Альтернативная команда без явного цикла (man find):

find . -type f -exec mv '{}' '{}'.jpg \;

Объяснение: это рекурсивно находит все файлы (-type f), начиная с текущего каталога (.), и применяет команду перемещения ( mv) каждому из них. Обратите внимание на кавычки вокруг {}, чтобы имена файлов с пробелами (и даже новые строки ...) обрабатывались правильно.

person Stephan202    schedule 10.07.2009
comment
В частности, этот работает лучше, если в структуре каталогов находится огромное количество файлов (из-за чего bash расстраивается из-за длины списка файлов для перебора). - person DrAl; 10.07.2009
comment
@Al, если вы ссылаетесь на цикл for, нарушающий bash, чтобы перебирать список файлов, это неверно. Цикл bash for итеративно выдает каждую mv команду. - person nik; 10.07.2009
comment
Вопрос: Создает ли find сначала список файлов перед выполнением оператора -exec? Думаю, да, но хочу прояснить этот момент перед написанием бесконечных циклов. - person Boldewyn; 10.07.2009
comment
@Boldewyn, я думаю, будет разумным избегать работы с символическими ссылками (с -P), если вы подозреваете возможный цикл. - person nik; 10.07.2009
comment
Хотя, думаю, символические ссылки по умолчанию пропускаются. - person nik; 10.07.2009
comment
эта команда также найдет файлы с расширением. Это то, чего хочет OP? - person ghostdog74; 10.07.2009
comment
@ ghostdog74: Поскольку он принял этот ответ, очевидно, что сказанное выше помогло. В противном случае, как вы упомянули ниже, добавление -not -name "*.*" поможет. - person Stephan202; 10.07.2009
comment
В моей версии bash кавычки вокруг {} не влияют на то, как find обрабатывает имена файлов с пробелами и т. Д. Вокруг них. Как вы это написали, команда find даже не увидит кавычек: они обрабатываются bash - person Adrian Pronk; 13.07.2009
comment
При этом я получаю следующую ошибку .. find: отсутствует аргумент для `-exec ' - person ArunMKumar; 04.07.2014
comment
к счастью, я выяснил, что не на собственном опыте, что это очень опасно с git. find не заботится о том, что .git скрыт намеренно, и добавит это расширение ко всем внутренностям этого репозитория git! Это означает, что вам нужно удалить все добавленные расширения из всей папки .git, что может быть такой же безумной задачей, как и изначально. - person gabeio; 03.02.2015
comment
используя это для генерации .sample версий файлов конфигурации :) - person scones; 26.07.2016

это найдет файлы без расширения и добавит ваш .jpg

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;
person ghostdog74    schedule 10.07.2009
comment
Это определенно обеспечит желаемый результат в 99% случаев. +1 - person les; 21.02.2015

Это немного поздно, но я подумал, что добавлю лучшее решение (хотя, возможно, менее читаемое), чем те, которые были до сих пор:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

Использование шаблона find | xargs обычно приводит к более эффективному выполнению, поскольку вам не нужно создавать новый процесс для каждого файла.

Обратите внимание, что для этого требуется версия переименования, которая есть в дистрибутивах со вкусом Debian (также известная как prename), а не традиционное переименование. Однако это всего лишь крошечный сценарий Perl, поэтому было бы достаточно легко использовать приведенную выше команду в любой системе.

person Chad Huneycutt    schedule 14.07.2009

нравится,

for f in $(find . -type f); do mv $f ${f}.jpg; done

Я не ожидаю, что у вас будут имена файлов, разделенные пробелами,
Если вы это сделаете, имена нужно будет немного обработать.

Если вы хотите выполнить команду из другого каталога,
вы можете заменить find . на find /target/directory.

person nik    schedule 10.07.2009
comment
Здесь отсутствует 'do', и если в имени файла есть пробелы, лучше указать имя файла в кавычках: для f в $ (find. -Type f); сделать mv $ f $ {f} .jpg; Выполнено - person DrAl; 10.07.2009
comment
и, предположительно, я бы запустил это из каталога верхнего уровня? - person robjmills; 10.07.2009
comment
@seengee: да. Обратите внимание, что в этой команде также отсутствует тире в -type. - person Stephan202; 10.07.2009
comment
Мне нужно было куда-то пойти и набрать слишком быстро ... сейчас поправляю. - person nik; 10.07.2009

Для переименования всех файлов без расширения в Windows basic вы можете сделать ren * *.jpg Поскольку файл не имеет расширения, просто используйте *, или, если вы хотите изменить png на jpg, используйте ren *.png *.jpg

person Nuno    schedule 08.11.2015

rename

не уверен, что он может переименовывать файлы без расширений (сейчас я на windows 7)

person dfa    schedule 10.07.2009
comment
он может, но он также будет переименовывать каталоги, и нет способа указать ему, чтобы он работал рекурсивно в подкаталогах (по крайней мере, с версией, которая у меня есть на Ubuntu). - person mirod; 10.07.2009
comment
Я знаю как минимум две разные команды, называемые rename, одна - программа на языке C, включенная в util-linux-ng, а другая - программа Perl (написанная самим Уоллом) на машинах Debian нашего университета. На самом деле ни один из них не выполняет рекурсию. - person Boldewyn; 10.07.2009