Skip to content

Instantly share code, notes, and snippets.

@dnozay
Forked from rjames86/My Exiftool Cheatsheet.md
Last active March 16, 2026 01:01
Show Gist options
  • Select an option

  • Save dnozay/955037f077b6dec87aa9b1eb552caf8d to your computer and use it in GitHub Desktop.

Select an option

Save dnozay/955037f077b6dec87aa9b1eb552caf8d to your computer and use it in GitHub Desktop.
Cheatsheet for image / video metadata manipulation.

Cheatsheet for image / video metadata manipulation.

Important options

-h  ➔  the most important of all, this cheatsheet is not exhaustive.
-s  ➔  use tag names instead of description, good for scripting since you want to use [-tagname] options.
-G  ➔  add group names to each tag, good if you deal with both Exif, XMP, etc.
-P  ➔  preserve [FileModifyDate], useful if you do not have any timestamp info in the file.

Examples

$ exiftool -s -G IMG_123.JPG
[show all metadata]

$ exiftool -AllDates IMG_123.JPG
Date/Time Original              : 2018:09:14 08:53:41
Create Date                     : 2018:09:14 08:53:41
Modify Date                     : 2018:09:14 08:53:41

$ exiftool -AllDates -s IMG_123.JPG
DateTimeOriginal                : 2018:09:14 08:53:41
CreateDate                      : 2018:09:14 08:53:41
ModifyDate                      : 2018:09:14 08:53:41

$ exiftool -DateTimeOriginal -s IMG_123.JPG
DateTimeOriginal                : 2018:09:14 08:53:41

$ exiftool -exif:DateTimeOriginal -G -s IMG_123.JPG
[EXIF]          DateTimeOriginal                : 2018:09:14 08:53:41

$ exiftool -xmp:DateTimeOriginal -G -s IMG_123.JPG
[nothing to see]

Reading metadata

Checking timestamps

exiftool -time:all -s .
exiftool -AllDates -s .

Searching for Files

This is often made more simple with conditions. If you need more advanced comparisons, learn Perl.

Find files with a jpg or jpeg extension

-ext jpg -ext jpeg

Find files without a DateTimeOriginal

-if '(not $datetimeoriginal)'

Or more specifically in a particular group

-if '(not ${exif:datetimeoriginal})'

Example

$ exiftool -s -G -filename -if '(${exif:datetimeoriginal})'  -ext jpg IMG_*
======== IMG_123.JPG
[File]          FileName                        : IMG_123.JPG
======== IMG_2131.jpg
[File]          FileName                        : IMG_2131.jpg
    2 image files read

Find files invalid DateTimeOriginal

Often enough, my battery is dead, and I put new ones in, but I forget to set the time on the camera.

-if '$DateTimeOriginal lt "2013:05:01 00:00:00"'

Find files that aren't named properly

I like to use ISO date in the filename.

-if '$filename !~ /^\d/'

Output photos that don't have datetimeoriginal to a CSV

Note this can take a long time if you have a lot of jpgs

# You'll need to set your Dropbox folder path. I have mine set as a global variable
OLDFILE="$DROPBOX_PERSONAL/nodates.csv"

FILECOUNT=$(mdfind -count -onlyin "$DROPBOX_PERSONAL" 'kMDItemKind =="JPEG image"')
while IFS= read -r -d '' n; do
    FILECOUNT=$(( $FILECOUNT - 1 ))
    if grep -q "$n" "$OLDFILE"; then
        echo "Skipping $n"
        continue
    fi

    echo -ne "Remaining: $FILECOUNT\r"
    exiftool -q -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00"))' -csv -common "$n" | sed 1d >> "$DROPBOX_PERSONAL/nodates.csv"
done < <( mdfind -onlyin "$DROPBOX_PERSONAL" 'kMDItemKind =="JPEG image"' -0 )

See files File Modify Date recursively in a directory who don't have datetimeoriginal set

exiftool -filemodifydate -r -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00")) and ($filetype eq "JPEG")' .

Modifying Files

Create Captions From a Filename

The command alone will put the full filename in the comments. If you want to add the filename without the extension, add the example exiftool config file found here

# This is the command if you have the config installed
exiftool '-Comment<BaseName' '-UserComment<BaseName' .

# Getting the filename without the config file, but with a for-loop
for i in *; do 
	FileName="${i%%.*}"
	exiftool "-Comment=$FileName" "-UserComment=$FileName" "$i";
done

Change JPG to jpg and MOV to mov in filenames

for i in *.JPG; do
    mv "$i" "${i%%.JPG}.jpg";
done
for i in *.MOV; do
    mv "$i" "${i%%.MOV}.mov";
done

or with bash skills

for i in *.JPG; do mv "$i" "${i%%.JPG}.jpg"; done; !#:gs/JPG/MOV/:gs/jpg/mov/

or alternatively with exiftool

exiftool '-filename=%f.%le' -ext jpg -ext mov *

example, using -testname instead to play pretend.

$ exiftool '-testname=%f.%le' IMG_*
'IMG_123.JPG' --> 'IMG_123.jpg'
Warning: File name is unchanged - IMG_2131.jpg
Warning: File name is unchanged - IMG_2132.jpeg
    0 image files updated
    3 image files unchanged

Change last created and modified for files in a directory

The date syntax has to be YYYY:MM:DD HH:MM:SS

Option 1:

find . -name "*.jpg" | while read filename;  
    exiftool "-AllDates=1986:11:05 12:00:00" "$filename";
done

Option 2:

exiftool "-AllDates=1986:11:05 12:00:00" -if '$filetype eq "JPEG"' .

Timeshift Photos by One Year

Info at Time Shift

exiftool "-AllDates+=1:0:0 0" .

Rename files to datestamp

Filename looks like 2014-01-01 12:00:00.jpg and will append -NUM if DateTimeOriginal is the same for multiple files

exiftool '-FileName<DateTimeOriginal' -d "%Y-%m-%d %H.%M.%S%%-c.%%e" .  

Rename Files to With Milliseconds

Good for burst photos where the seconds are all the same. If milliseconds are only out to 2 digits, use ${SubSecCreateDate} instead

Found at this forum post.

exiftool -v '-Filename<${datetimeoriginal}${subsectimeoriginal;$_.=0 x(3-length)}.%e' -d %Y%m%d_%H%M%S .

Update any photo that doesn't have DateTimeOriginal to have it based on file modify date

exiftool \
    '-datetimeoriginal<filemodifydate' \
    -if '(not $datetimeoriginal or ($datetimeoriginal eq "0000:00:00 00:00:00")) and ($filetype eq "JPEG")' \
    .

Set DateTimeOriginal to Any Arbitrary Timestamp

exiftool '-datetimeoriginal=2015:01:18 12:00:00' .

Moving/Copying Files

Copy directory recursively into organized folder

exiftool \
    -o ~/dummy/ \
    -if '$filesize# > 300000' \        
    '-Directory<CreateDate' \
    -d "~/Desktop/old_photos2/%Y/%m %B" \
    -r "~/Desktop/iPhoto Library/"
  • -o ~/dummy This flag is to copy, not move. The directory is a fallback if the flag isn't available on the given photo. Good if using something like DateTimeOriginal

  • -if '$filesize# > 300000' gets files that are over 300kB. I was parsing an iPhoto library where there were thumbnails. The # turns the value to a number. you can use the flag -n to turn all values to numbers

  • '-Directory<CreateDate' Create directories based on the CreateDate of the photos

  • -d "~/Desktop/old_photos/%Y/%m %B" Create folders with the given date format.

  • -r Run recursively

Geotagging

To tag all my ULM pictures with coordinates -21.152441, 55.279274.

exiftool \
    -exif:gpslatituderef=-1 \
    -exif:gpslatitude=-21.152441 \
    -exif:gpslongituderef=1 \
    -exif:gpslongitude=55.279274 \
    *ULM*

Create KML from geotagged photos

DESKTOP=$HOME/Desktop
cat $DESKTOP/kml-start.fmt > out.kml
exiftool -n -r -q -p $DESKTOP/kml-placemark.fmt . >> out.kml
cat $DESKTOP/kml-end.fmt >> out.kml

Create CSV of Geo Information

exiftool -csv -filename -imagesize -gps:GPSLatitude -gps:GPSLongitude ./ > long.csv

References

Update Notes

  • 2019-07-24 - added more commands for searching for files, fix title formatting, geotagging example
  • 2017-03-18 - added command to create comments from a filename
  • 2015-08-11 - added line to rename files based on milliseconds
  • 2015-01-18 - added line on how to set a date for a particular photo(s)
  • 2014-12-26 - Adding new recursive command to rename JPG to jpg. Info on using sh with -exec here
  • 2014-12-25 - Added line for copying photos into organized photos.
@dnozay
Copy link
Author

dnozay commented Jul 24, 2019

@dnozay
Copy link
Author

dnozay commented Jul 24, 2019

http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=8359.0

exiftool -if '$ShutterCount' '-FileName<${ShutterCount; $_ = substr("000000$_",-6);}.%e' -r DIR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment