Удалить часть имени файла в папке?

Моя камера хранит фотографии в следующем формате:

DSC_0001 (2015_07_30 10_34_56 UTC).NEF 

С числом после итерации DSC_ и скобками, указывающими время и дату, однако вся информация о времени и дате содержится в метаданных, поэтому я хочу переименовать все файлы, которые она создает:

 DSC_0001.NEF etc 

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

Если бы вы могли объяснить, почему то, что вы предлагаете, работает, я был бы благодарен, чтобы я мог попытаться узнать, как исправить подобные проблемы в будущем.

ПРИМЕЧАНИЕ: я использую Bash, если это имеет значение.

С помощью инструмента переименования Perl:

 rename 's/ \(.*?\)//' *.NEF 

Регулярное выражение должно быть простым ( .*? Соответствует самой короткой строке).

Посмотрим, почему утилита переименования в Debian / Ubuntu отличается от утилиты в других дистрибутивах, таких как CentOS? о двух разных командах rename .

Если файлы находятся в одной папке без подкаталогов и эта папка называется photos :

 for pathname in photos/*(*).NEF; do newname=${pathname##*/} newname=${newname%% '('*}.NEF printf 'Would move "%s" to "%s"\n' "$pathname" "${pathname%/*}/$newname" # mv -i "$pathname" "${pathname%/*}/$newname" done 

Это будет повторять все имена файлов на photos , имена которых содержат ( и заканчиваются ).NEF . Новое имя файла создается путем удаления имени каталога из текущего пути, а затем удаления всего после ␣( (пробел и ( ) в том, что осталось, и добавления .NEF в конце имени.

Фактическое переименование файлов закомментировано для безопасности.

Пример вывода кода выше:

 Would move "photos/DSC_0001 (2015_07_30 10_34_56 UTC).NEF" to "photos/DSC_0001.NEF" 

Если файлы находятся где-то в более крупной структуре каталогов:

 find photos -type f -name '*(*).NEF' -exec sh -c ' for pathname do newname=${pathname##*/} newname=${newname%% \(*}.NEF printf "Would move "%s" to "%s"\n" "$pathname" "${pathname%/*}/$newname" # mv -i "$pathname" "${pathname%/*}/$newname" done' sh {} + 

Единственное отличие здесь – это способ, которым имена путей к соответствующим файлам генерируются для цикла. В этом случае find передает пакеты найденных путей в цикл, но сам цикл такой же, как и в первом бите этого ответа (с некоторыми незначительными изменениями в кавычках).

Связанные с:

  • Понимание опции -exec `find`

Если во всех именах файлов (а не в пути) есть пара пробел-скобка ( ( ), вы можете использовать:

 mv "$f" "${f%% (*}.NEF" 

Чтобы перебрать все файлы, выполните:

 $ for f in dir/*\(*\).NEF; do [ -f "$f" ] && mv "$f" "${f%% (*}.NEF"; done 

Вы должны быть в каталоге, где находятся файлы

 let a=0; for i in *.NEF; do let a=a+1; b=`basename $PWD`; c=`printf %04d$b.NEF $a`; mv $i $c; done 

Переименовать все в одно и то же время.