Como renomear várias fotos e vídeos com base em dados EXIF?

11

Geralmente importo fotos e vídeos (principalmente com extensões JPG e MOV) de câmeras digitais e tablets para o meu PC e, idealmente, gostaria de vê-los classificados de acordo com as datas e horas em que foram tiradas já presentes nos dados EXIF. E, portanto, meu desejo de renomeá-los todos, de preferência usando um script Nautilus simples, inserindo preferencialmente os carimbos de data e hora antes de cada nome de arquivo.

Até agora, consegui apenas reunir o seguinte script Nautilus, que acredito estar longe de ser perfeito:

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

O que eu não gosto nesse método de renomeação são os dois pontos usados ​​nos carimbos de data e hora EXIF (por exemplo, "2013: 09: 03 20: 55: 09_IMG_0108.JPG"), que podem criar problemas ao transferir esses arquivos posteriormente para outros ambientes ( por exemplo, Windows).

Este comando (usando o exiv2 em vez do exiftool ) habilita convenientemente a manipulação de carimbos de data e hora, mas sua desvantagem é que ele não funciona em arquivos de vídeo (por exemplo, MOV) :

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

Então, espero que alguém possa encontrar uma solução melhor. E seria mágico se ele conseguisse converter os nomes de arquivos e extensões originais em minúsculas também!

Sadi
fonte
Além das ótimas respostas abaixo, você também deve conferir o pyRenamer . Não tenho experiência em usá-lo com arquivos de vídeo (eles têm dados EXIF?), Mas posso dizer que é excelente para fotos. Também pode alterar as extensões de arquivo para minúsculas.
Tom Brossman

Respostas:

6

O que eu não gosto nesse método de renomeação são os dois pontos usados ​​nos carimbos de data e hora EXIF ​​(por exemplo, "2013: 09: 03 20: 55: 09_IMG_0108.JPG"), que podem criar problemas ao transferir esses arquivos posteriormente para outros ambientes ( por exemplo, Windows).

Você pode executar o esquema de nomenclatura sedpara substituir os dois pontos por hífens e espaços por sublinhados, da seguinte maneira:

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

Quanto a tornar a coisa toda em minúscula, você pode usar rename:

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

Ou você pode fazê-lo em seu script usando sed, como em:

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

... e use a $jvariável no lugar da final $ida sua mvlinha. Essa maneira sed é um pouco mais portátil (se isso for importante para você), pois diferentes distros linux têm diferentes comandos de renomeação, enquanto sed é universal.

Ou, alternativamente, o script pode ser modificado da seguinte maneira para executar a conversão do nome do arquivo para minúscula no início usando 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

Para executar comandos ligeiramente diferentes para diferentes tipos de arquivo, uma instrução bash case pode ser usada neste script. Por exemplo:

#! /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

Neste exemplo, a renomeação de arquivos MOV com registros de data e hora de CreateDate QUALQUER NÚMERO DE HORAS APÓS OU ANTES DE arquivos JPG é ajustada usando outros dados EXIF ​​(-tur) e removendo esse sufixo de diferença de horário, e pode ser necessário alterar a parte -tur de acordo com o local definido no sistema.

evilsoup
fonte
Infelizmente, não consegui descobrir como converter nomes de arquivos em minúsculas, como você sugere (inserir essa linha acima e alterar a última $ipara $jnão fazer nada). Em vez disso, inseri a conversão do nome do arquivo em minúscula no início e tomei a liberdade de adicionar isso como outra opção (que funcionou pelo menos para mim) ao final da sua resposta, para que eu possa aceitá-la. Claro que você pode editar sua resposta ainda mais, conforme desejar.
Sadi
@sadi olhando para ele com novos olhos, posso ver o que estava fazendo de errado com o comando sed. A versão mais recente funcionará, embora, é claro, se o método tr funcione para você, isso é bom (tenho uma suspeita furtiva de que a solução tr possa ser um pouco mais eficiente, na verdade, embora o sed um lide com caracteres não ingleses)
evilsoup
Obrigado. Gostaria de saber se você também pode me ajudar a melhorar esse script usando um comando para arquivos MOV e outro para outros ao longo das linhas: se [a extensão é MOV] blá blá; mais blá blá. O motivo é que acabei de perceber que o carimbo "CreateDate" nos meus arquivos MOV (do iPad) tem estranhamente +4 horas e preciso usar outra opção (CreateDate-tur) para que eles obtenham uma ordem precisa de fotos e vídeos .
Sadi
A melhor maneira para isso (na minha opinião) é usar uma declaração de caso; aqui está algo para você começar. Você também pode usar uma instrução if, mas as instruções de caso podem ser mais facilmente expandidas para extensões de arquivo extras. Pesquise na Internet por 'bash case statement' para obter mais informações.
precisa saber é o seguinte
Graças um milhão !!! Também adicionarei esta opção à resposta, se você não se importa.
Sadi
13

Eu precisava renomear minhas fotos e encontrei esta pergunta aqui - acabei de descobrir que exiftoollida com isso de forma nativa:

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

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

Se você deseja acompanhar o nome do arquivo original e escrever em minúsculas a extensão:

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

O mesmo funciona também com o nome do arquivo inteiro em minúsculas:

exiftool -d %Y%m%d_%H%M%S%%-c-%%lf.%%le "-filename<DateTimeOriginal" [.|DIR]
DerekC
fonte
DIR deve ser a pasta onde as fotos estão alocadas. Se já abrimos um terminal na pasta onde queremos executar o comando, precisamos substituir o DIR por. E se você deseja adicionar um prefixo, ao nome do arquivo (ou seja, IMG_), ele deve ser inserido antes da cadeia de datas sem nenhuma citação. Aqui está um exemplo: exiftool -d IMG_% Y% m% d_% H% M% S %% - c. %% e "-filename <CreateDate".
Notre15 de
2

Sei que você disse que preferia um script, no entanto, se você está aberto para um aplicativo Java gratuito, pode usar o AmoK Exif Sorter

insira a descrição da imagem aqui

opticíclico
fonte
1

Eu usaria krenamepara isso. isto

  • mostra visualização ao vivo
  • permite desfazer
  • pode ir recursivamente para dir
  • permite vários padrões de renomeação
  • permite globs e regexps em padrões
  • lembra história
Adobe
fonte
0

O pyrenamer não funcionará no meu novo Ubuntu 16.04 instalado; portanto, também tenho que encontrar outra maneira de resolver esse problema.

Eu tenho arquivos como IMG_0001.JPG, IMG_0002.JPG, ... em uma pasta. Verifique este site, /programming/917260/can-var-parameter-expansion-expressions-be-nested-in-bash

Instale o "exiv2" primeiro e escrevi a seguinte linha de comando:

para img em $ (ls *. [Jj] [Pp] [Gg] 2> / dev / null); exiv2 -r '% Y% m% d_% H% M% S _' "$ (tmp = $ {img %%. *}; echo $ {tmp ## * _})" renomeie "$ img"; feito

Os nomes dos arquivos de saída são AAAAMMDD_HHMMSS_0001.JPG, AAAAMMDD_HHMMSS_0002.JPG, ... etc. Até as fotos foram tiradas no mesmo segundo, o número de série da foto original fará a diferença.

chuck lee
fonte