Как переименовать несколько фотографий и видео на основе данных EXIF?

11

Я часто импортирую фотографии и видео (в основном с расширениями JPG и MOV) с цифровых камер и планшетов на мой компьютер, и в идеале я бы хотел, чтобы они были отсортированы по датам и времени, когда они были уже представлены в их данных EXIF. И, следовательно, мое желание переименовать их, желательно, используя простой скрипт Nautilus , предпочтительно вставляя метки даты и времени перед каждым именем файла.

До сих пор мне удалось собрать только следующий сценарий Наутилуса, который, я считаю, далек от совершенства:

for i in *.*
do
mv -i "$i" "$(exiftool -CreateDate "$i" | awk -F ': ' '{print $2}')_"$i"" 
done

В этом методе переименования мне не нравятся двоеточия, используемые в метках даты и времени EXIF (например, «2013: 09: 03 20: 55: 09_IMG_0108.JPG»), которые могут создавать проблемы при последующей передаче этих файлов в другие среды ( например, Windows).

Эта команда (использующая exiv2 вместо exiftool ) позволяет легко манипулировать метками даты и времени, но ее недостатком является то, что она не работает с видеофайлами (например, MOV) :

exiv2 -k -r '%Y-%m-%d_%H-%M-%S_:basename:' rename "$i"

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

Сади
источник
В дополнение к отличным ответам ниже вы также должны проверить pyRenamer . У меня нет опыта использования его с видеофайлами (есть ли у них данные EXIF?), Но я могу сказать, что это отлично подходит для фотографий. Он также может изменять расширения файлов в нижнем регистре.
Том Броссман

Ответы:

6

В этом методе переименования мне не нравятся двоеточия, используемые в метках даты и времени EXIF ​​(например, «2013: 09: 03 20: 55: 09_IMG_0108.JPG»), которые могут создавать проблемы при последующей передаче этих файлов в другие среды ( например, Windows).

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

mv -i "$i" "$(exiftool -CreateDate "$i" | awk -F ': ' '{print $2}' | sed -e 's/:/-/g' -e 's/ /_/g')_$i"

Что касается строчных букв, вы можете использовать rename:

rename 's/(.*)/\L$1/' file.JPG
##  or
rename 's/(.*)/\L$1/' *.*

Или вы можете сделать это в вашем скрипте, используя sed:

j=$(echo "$i" | sed -e 's/\(.*\)/\L\1/')

... а затем используйте $jпеременную вместо финала $iвашей mvстроки. Этот способ sed немного более переносим (если это важно для вас), поскольку разные дистрибутивы Linux имеют разные команды переименования, а sed универсален.

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

for arg 
do
  tmp="$(echo "$arg" | tr '[A-Z]' '[a-z]')"
  mv -i "$arg" "$(exiftool -CreateDate "$arg" | awk -F ': ' '{print $2}' | sed -e 's/:/-/g' -e 's/ /_/g')_$tmp"
done

Чтобы выполнить немного разные команды для разных типов файлов, в этом сценарии можно использовать оператор bash case. Например:

#! /usr/bin/env bash
for filename in ./*
do
  tmp="$(echo "$filename" | tr '[A-Z]' '[a-z]')"
  case "$filename" in
    *.MOV|*.mov) 
      mv -i "$filename" "$(exiftool -a -s -CreateDate-tur "$filename" | awk -F ': ' '{print $2}' | sed -e 's/\-[0-9][0-9]\:00//g' -e 's/\+[0-9][0-9]\:00//g' -e 's/:/-/g' -e 's/ /_/g')_$tmp"
      ;;
    *.JPG|*.jpg)
      mv -i "$filename" "$(exiftool -a -s -CreateDate "$filename" | awk -F ': ' '{print $2}' | sed -e 's/:/-/g' -e 's/ /_/g')_"$tmp""
      ;;
    *)
      echo 'Not a *.jpg or a *.mov!'
      ;;
  esac
done

В этом примере переименование файлов MOV, имеющих метки времени CreateDate ЛЮБОЕ ЧИСЛО часов ПОСЛЕ ИЛИ ДО ДОПОЛНЕНИЯ JPG-файлов, корректируется с использованием других (-tur) EXIF-данных и удаления этого суффикса разницы во времени, и может потребоваться изменить часть -tur в соответствии с местоположением, установленным в системе.

evilsoup
источник
К сожалению, я не мог понять, как преобразовать имена файлов в нижний регистр, как вы предлагаете (вставив эту строку выше и изменив последнюю, $iчтобы $jничего не происходило). Вместо этого я вставил преобразование имени файла в нижний регистр в начале и позволил себе добавить это как еще один вариант (который работал по крайней мере для меня) в конец вашего ответа, чтобы я мог принять ваш ответ. Конечно, вы можете редактировать свой ответ дальше, как пожелаете.
Сади
@sadi смотрит на это свежим взглядом, я вижу, что я делал неправильно с командой sed. Последняя версия будет работать, хотя, конечно, если метод tr работает для вас, это нормально (у меня есть подозрение, что решение tr может быть немного более эффективным, хотя sed лучше будет обрабатывать неанглийские символы)
evilsoup
Спасибо. Интересно, можете ли вы также помочь мне улучшить этот сценарий, используя одну команду для файлов MOV, а другую - для других: if [extension is MOV] blah blah; еще бла-бла. Причина в том, что я только что понял, что штамп «CreateDate» в моих файлах MOV (с iPad) странным образом имеет +4 часа, и мне нужно использовать другой параметр (CreateDate-tur) для них, чтобы добиться точного порядка фотографий и видео ,
Сади
Лучший способ для этого (на мой взгляд) состоит в использовании описания случая; Вот кое-что, чтобы вы начали. Вы также можете использовать оператор if, но операторы case могут быть легко расширены для дополнительных расширений файлов. Поищите в интернете «выписка по делу bash» для получения дополнительной информации.
evilsoup
Бесконечно благодарен!!! Я также добавлю эту опцию в ответ, если вы не возражаете.
Сади
13

Мне нужно было переименовать мои фотографии и найти этот вопрос здесь - я только что узнал, что exiftoolобрабатывает его изначально:

От http://www.sno.phy.queensu.ca/~phil/exiftool/filename.html

exiftool -d %Y-%m-%d_%H-%M-%S%%-c.%%e "-filename<CreateDate" DIR 

Если вы хотите отслеживать исходное имя файла и писать расширение в нижнем регистре:

exiftool -d %Y%m%d_%H%M%S%%-c-%%f.%%le "-filename<DateTimeOriginal" [.|DIR]

То же самое работает и со всем именем файла в нижнем регистре:

exiftool -d %Y%m%d_%H%M%S%%-c-%%lf.%%le "-filename<DateTimeOriginal" [.|DIR]
DerekC
источник
DIR должна быть папкой, в которой размещены фотографии. Если мы уже открыли Терминал в Папке, где мы хотим выполнить Команду, мы должны заменить DIR для. И если вы хотите добавить префикс к имени файла (т.е. IMG_), он должен быть вставлен перед цепочкой дат без кавычек. Вот пример: exiftool -d IMG_% Y% m% d_% H% M% S %% - c. %% e "-filename <CreateDate".
Nothor
2

Я знаю, что вы сказали, что предпочитаете скрипт, однако, если вы открыты для бесплатного Java-приложения, вы можете использовать AmoK Exif Sorter

введите описание изображения здесь

opticyclic
источник
1

Я бы использовал krenameдля этого. Это

  • показывает предварительный просмотр
  • позволяет отменить
  • может рекурсивно войти в каталог
  • позволяет несколько шаблонов переименования
  • позволяет глобусы и регулярные выражения в шаблонах
  • помнит историю
саман
источник
0

Pyrenamer не будет работать на моем новом установленном Ubuntu 16.04, поэтому я должен найти другой способ решить эту проблему.

У меня есть файлы, такие как IMG_0001.JPG, IMG_0002.JPG, ... в одной папке. Проверьте этот сайт, /programming/917260/can-var-parameter-expansion-expressions-be-nested-in-bash

Сначала установите exiv2, и я написал следующую командную строку:

для img в $ (ls *. [Jj] [Pp] [Gg] 2> / dev / null); do exiv2 -r '% Y% m% d_% H% M% S _' "$ (tmp = $ {img %%. *}; echo $ {tmp ## * _})" rename "$ img"; сделанный

Выходные имена файлов: YYYYMMDD_HHMMSS_0001.JPG, YYYYMMDD_HHMMSS_0002.JPG, ... и т. Д. Даже если фотографии были сделаны в одну секунду, оригинальный серийный номер фотографии будет иметь значение.

Чак Ли
источник