Jak zmienić nazwę wielu zdjęć i filmów na podstawie danych EXIF?

11

Często importuję zdjęcia i filmy (głównie z rozszerzeniami JPG i MOV) z cyfrowych aparatów fotograficznych i tabletów na komputer i idealnie chciałbym, aby były posortowane według dat i godzin, w których zostały już zapisane w danych EXIF. Dlatego pragnę zmienić ich nazwy, najlepiej używając prostego skryptu Nautilus , najlepiej wstawiając datę i godzinę przed każdą nazwą pliku.

Do tej pory udało mi się zebrać tylko następujący Skrypt Nautilusa, który moim zdaniem nie jest doskonały:

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

W tej metodzie zmiany nazwy nie podoba mi się dwukropek używany w znacznikach daty i godziny EXIF (np. „2013: 09: 03 20: 55: 09_IMG_0108.JPG”), które mogą powodować problemy podczas późniejszego przesyłania tych plików do innych środowisk ( np. Windows).

To polecenie (używając exiv2 zamiast exiftool ) wygodnie umożliwia manipulowanie znacznikami daty i godziny, ale jego wadą jest to, że nie działa na plikach wideo (np. MOV) :

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

Mam nadzieję, że ktoś wymyśli lepsze rozwiązanie. Byłoby magiczne, gdyby udało się nawet przekonwertować oryginalne nazwy plików i rozszerzenia na małe litery!

Sadi
źródło
Oprócz świetnych odpowiedzi poniżej, powinieneś również sprawdzić pyRenamer . Nie mam doświadczenia w używaniu go z plikami wideo (czy mają dane EXIF?), Ale mogę powiedzieć, że jest doskonały do ​​zdjęć. Może także zmieniać rozszerzenia plików na małe litery.
Tom Brossman,

Odpowiedzi:

6

W tej metodzie zmiany nazwy nie podoba mi się dwukropek używany w znacznikach daty i godziny EXIF ​​(np. „2013: 09: 03 20: 55: 09_IMG_0108.JPG”), które mogą powodować problemy podczas późniejszego przesyłania tych plików do innych środowisk ( np. Windows).

Możesz uruchomić schemat nazewnictwa sed, aby zastąpić dwukropki myślnikami, a spacje podkreślnikami:

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

Jeśli chodzi o małe litery, możesz użyć rename:

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

Lub możesz to zrobić w skrypcie, używając sed:

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

... a następnie użyć $jzmiennej w miejsce finał $itwojej mvlinii. Ten sposób sedowania jest nieco bardziej przenośny (jeśli jest to dla Ciebie ważne), ponieważ różne dystrybucje linuksowe mają różne polecenia zmiany nazwy, podczas gdy sed jest uniwersalny.

Ewentualnie skrypt można zmodyfikować w następujący sposób, aby na początku przeprowadzić konwersję nazwy pliku na małe litery, używając 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

Aby wykonać nieco inne polecenia dla różnych typów plików, w tym skrypcie można użyć instrukcji case bash. Na przykład:

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

W tym przykładzie zmiana nazwy plików MOV, które mają znaczniki czasu CreateDate DOWOLNĄ LICZBĘ GODZIN PO LUB PRZED plikami JPG, jest dostosowywana przy użyciu innych danych (-tur) EXIF ​​i usunięcia tego sufiksu różnicy czasu i może być konieczna zmiana części -tur zgodnie z lokalizacją ustawioną w systemie.

zła
źródło
Niestety nie mogłem wymyślić, jak przekonwertować nazwy plików na małe litery, jak sugerujesz (wstawienie tej linii powyżej i zmiana ostatniej $ina $jnic nie zrobiła). Zamiast tego na początku wstawiłem konwersję nazwy pliku na małe litery i mogłem dodać to jako kolejną opcję (która działała przynajmniej dla mnie) na końcu twojej odpowiedzi, dzięki czemu mogę przyjąć twoją odpowiedź. Oczywiście możesz dowolnie edytować swoją odpowiedź.
Sadi
@sadi patrząc na to świeżymi oczami, widzę, co robiłem źle z poleceniem sed. Najnowsza wersja będzie działać, choć oczywiście jeśli metoda tr będzie dla ciebie odpowiednia, to w porządku (podejrzewam, że rozwiązanie tr może być nieco bardziej wydajne, chociaż sed lepiej poradzi sobie ze znakami innymi niż angielskie)
evilsoup
Dziękuję Ci. Zastanawiam się, czy możesz mi pomóc w dalszym ulepszaniu tego skryptu, używając jednego polecenia dla plików MOV, a drugiego dla innych: jeśli [rozszerzenie to MOV] bla bla; inaczej bla bla. Powodem jest to, że właśnie zdałem sobie sprawę, że znaczek „CreateDate” w moich plikach MOV (z iPada) ma dziwnie +4 godziny i muszę użyć innej opcji (CreateDate-tur), aby uzyskać dokładną kolejność zdjęć i filmów .
Sadi
Moim zdaniem najlepszym sposobem na to jest użycie instrukcji case; oto coś na początek. Możesz także użyć instrukcji if, ale instrukcje case można łatwiej rozwinąć o dodatkowe rozszerzenia plików. Wyszukaj w Internecie „bash case statement”, aby uzyskać więcej informacji.
evilsoup
Stukrotne dzięki!!! Dodam tę opcję do odpowiedzi, jeśli nie masz nic przeciwko.
Sadi
13

Musiałem zmienić nazwę moich zdjęć i znalazłem to pytanie tutaj - właśnie dowiedziałem się, że exiftoolobsługuje je natywnie:

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

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

Jeśli chcesz śledzić oryginalną nazwę pliku i napisać małe litery rozszerzenia:

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

To samo działa również z całą nazwą pliku pisaną małymi literami:

exiftool -d %Y%m%d_%H%M%S%%-c-%%lf.%%le "-filename<DateTimeOriginal" [.|DIR]
DerekC
źródło
DIR musi być folderem, do którego przydzielane są zdjęcia. Jeśli już otworzyliśmy terminal w folderze, w którym chcemy wykonać polecenie, musimy zastąpić DIR. A jeśli chcesz dodać prefiks, do nazwy pliku (tj. IMG_) należy go wstawić przed łańcuchem dat bez cudzysłowu. Oto przykład: exiftool -d IMG_% Y% m% d_% H% M% S %% - c. %% e "-filename <CreateDate".
Nothor,
2

Wiem, że powiedziałeś, że wolisz skrypt, ale jeśli jesteś otwarty na bezpłatną aplikację Java, możesz użyć AmoK Exif Sorter

wprowadź opis zdjęcia tutaj

optycykliczny
źródło
1

Użyłbym krenametego. To

  • pokazuje podgląd na żywo
  • pozwala cofnąć
  • może przejść rekursywnie w reż
  • pozwala na wiele wzorów zmiany nazw
  • umożliwia globusy i wyrażenia regularne we wzorach
  • pamięta historię
Cegła suszona na słońcu
źródło
0

Pyrenamer nie będzie działał na moim nowym zainstalowanym Ubuntu 16.04, dlatego też muszę znaleźć inny sposób rozwiązania tego problemu.

Mam pliki takie jak IMG_0001.JPG, IMG_0002.JPG, ... w jednym folderze. Sprawdź tę stronę, /programming/917260/can-var-parameter-expansion-expressions-be-nested-in-bash

Najpierw zainstaluj „exiv2”, a ja napisałem następujący wiersz poleceń:

dla img w $ (ls *. [Jj] [Pp] [Gg] 2> / dev / null); wykonaj exiv2 -r '% Y% m% d_% H% M% S _' "$ (tmp = $ {img %%. *}; echo $ {tmp ## * _})" zmień nazwę "$ img"; gotowy

Wyjściowe nazwy plików to RRRRMMDD_GGMMSS_0001.JPG, RRRRMMDD_HHMMSS_0002.JPG, ... itd. Nawet zdjęcia zostały zrobione w tej samej sekundzie, oryginalny numer seryjny zdjęcia zrobi różnicę.

Chuck Lee
źródło