###############################################################################
#
# Standard Alias: Uncomment the ALIASES entries you elect to use from this section
#
###############################################################################
#alias vibashl='vi ~/.bash_login'
#alias ll='ls -lisahG'
# Keep colors on ls and more/less.
# See: http://mockingeye.com/piping-ls-through-less-with-colors-on-mac-os/
#alias llc='CLICOLOR_FORCE=1 ls -lisahG'
#alias less='less -R'
#alias more='more -R'
#alias ll='ls -lisahG'
#alias dir='ll'
#alias rm='rm -i'
#alias calc='bc'
#alias md='mkdir'
#alias grep='grep --color=auto'
#alias egrep='egrep --color=auto'
#alias Preview='open -a Preview'
# New Prompt
# export PS1='\n\h#\w>\n\t \u \W[\!]> '
###############################################################################
#
# EXIFTOOL related commands
#
###############################################################################
#==============================================================================
# exif()
#------------------------------------------------------------------------------
function exif() {
# To overcome incompatibility of xattr (loaded by osxphotos).
# Force PATH to force xattr to be sourced from /usr/bin
# Place format.fmt (attached) in your home folder.
PATH=/usr/bin:$PATH exiftool -r -d """%Y:%m:%d %H:%M:%S""" -p """~/format.fmt""" -f "$@"
}
export -f exif
function exiforiginaldate () {
echo Performing... """-CreateDate\<DateTimeOriginal""" """-FileModifyDate\<DateOriginalDate"""
# 2017.04.13 Included changing the ModifyDate tag (operating system level, which could also be set via touch command)
exiftool -d """%Y:%m:%d %H:%M:%S""" -overwrite_original_in_place -fileOrder DateTimeOriginal """-CreateDate<DateTimeOriginal""" """-FileModifyDate<DateTimeOriginal""" """-ModifyDate<DateTimeOriginal""" -v "$@"
}
export -f exiforiginaldate
function exifcreatedate (){
echo Performing... ""-DateTimeOriginal\<CreateDate"" ""-FileModifyDate\<CreateDate""
exiftool -d """%Y:%m:%d %H:%M:%S""" -overwrite_original_in_place -fileOrder DateTimeOriginal """-DateTimeOriginal<CreateDate""" """-FileModifyDate<CreateDate""" -v "$@"
}
export -f exifcreatedate
function exifmodifydate () {
echo Performing... ""-DateTimeOriginal\<FileModifyDate"" ""-CreateDate\<FileModifyDate""
exiftool -overwrite_original_in_place """-DateTimeOriginal<FileModifyDate""" """-CreateDate<FileModifyDate""" """-ModifyDate<FileModifyDate""" -P -v "$@"
}
export -f exifmodifydate
# Used for Pixel phones (PXL) captured video mp4A to get ModifyDate and not FileModifyDate
function exifrecover_modifydate () {
echo Performing... ""-DateTimeOriginal\<ModifyDate"" ""-CreateDate\<ModifyDate""
exiftool -overwrite_original_in_place """-DateTimeOriginal<ModifyDate""" """-CreateDate<ModifyDate""" """-ModifyDate<ModifyDate""" -P -v "$@"
}
export -f exifrecover_modifydate
function exifKeysdate () {
echo Performing... ""-DateTimeOriginal\<Keys:CreationDate""
exiftool -overwrite_original_in_place """-DateTimeOriginal<Keys:CreationDate""" -P -v "$@"
}
export -f exifKeysdate
function exifpng2jpg() {
# Command which convert .PNG files into .JPG and copies EXIF fields ...
for a in "$@"
do
fname=`basename "$a" .png`
xtension=png
echo 1st - ${fname}.${xtension}
if [ \( -f "${fname}".png -o -f "${fname}".PNG \) -a ! -f "${fname}".jpg ]
then
echo ok - ${fname}.${xtension}
sips -s format jpeg -s formatOptions 90 """${fname}".${xtension}"" --out """${fname}".jpg""
exiftool -overwrite_original_in_place -TagsFromFile "${fname}".${xtension} "-all:all>all:all" "${fname}".jpg
else
fname=`basename "$a" .PNG`
xtension=PNG
echo 2nd - ${fname}.${xtension}
if [ \( -f "${fname}".png -o -f "${fname}".PNG \) -a ! -f "${fname}".jpg ]
then
echo ok - ${fname}.${xtension}
sips -s format jpeg -s formatOptions 90 """${fname}".${xtension}"" --out """${fname}".jpg""
exiftool -overwrite_original_in_place -TagsFromFile "${fname}".${xtension} "-all:all>all:all" "${fname}".jpg
fi
fi
done
}
export -f exifpng2jpg
function exiftif2jpg() {
# Command which convert .TIF files into .JPG and copies EXIF fields ... Uses ModifyDate as the source for DateTimeOriginal, FileModifyDate, CreateDate fields
for a in "$@"
do
fname=`basename "$a" .tif`
dname=`dirname "$a" `
if [ -f "${dname}/${fname}".tif -a ! -f "${dname}/${fname}".jpg ]
then
echo ok - ${fname}
sips -s format jpeg -s formatOptions 100 """${dname}/${fname}".tif"" --out """${dname}/${fname}".jpg""
exiftool -overwrite_original_in_place -TagsFromFile "${dname}/${fname}".tif "-all:all>all:all" "${dname}/${fname}".jpg
# WHy am I using ModifyDate and referencing FileModifyDate?
echo Performing... ""-DateTimeOriginal\<FileModifyDate"" ""-CreateDate\<FileModifyDate"" on "${dname}/${fname}".jpg
exiftool -overwrite_original_in_place """-DateTimeOriginal<ModifyDate""" """-CreateDate<ModifyDate""" """-FileModifyDate<ModifyDate""" -P -v "${dname}/${fname}".jpg
fi
done
}
export -f exiftif2jpg
function exifsetdate() {
datetoset=${1}; echo $datetoset
shift
exiftool -d """%Y:%m:%d %H:%M:%S""" -overwrite_original_in_place -fileOrder DateTimeOriginal -DateTimeOriginal="""${datetoset}""" -v "$@"
}
export -f exifsetdate
function exifresetcreatedate() {
datetoset=${1}; echo $datetoset
shift
exiftool -d """%Y:%m:%d %H:%M:%S""" -overwrite_original_in_place -fileOrder DateTimeOriginal -CreateDate="""${datetoset}""" -v "$@"
}
export -f exifresetcreatedate
function exifresetmodifydate() {
datetoset=${1}; echo $datetoset
shift
exiftool -d """%Y:%m:%d %H:%M:%S""" -overwrite_original_in_place -fileOrder DateTimeOriginal -FileModifyDate="""${datetoset}""" -v "$@"
}
export -f exifresetmodifydate
function exifsetalldates() {
datetoset=${1}; echo $datetoset
shift
exiftool -d """%Y:%m:%d %H:%M:%S""" -overwrite_original_in_place -fileOrder DateTimeOriginal -DateTimeOriginal="""${datetoset}""" -CreateDate="""${datetoset}""" -FileModifyDate="""${datetoset}""" -ModifyDate="""${datetoset}""" -v "$@"
}
export -f exifsetalldates
function exifrenamefile() {
#exiftool -v4 -r -d """%Y-%m-%d %H.%M.%S%%-c.%%le""" '-filename<DateTimeOriginal' -f "$@"
# %%le lowers the case of extension. Hopefully %%e keeps the same extension
exiftool -v4 -r -d """IMG_%Y%m%d_%H%M%S%%-c.%%e""" '-filename<DateTimeOriginal' -f "$@"
echo "Note: Do you need to run exiforiginaldate?"
}
export -f exifrenamefile
#==============================================================================
# exifsetMVI()
#------------------------------------------------------------------------------
function exifsetMVI() {
E_BADARGS=85
E_BADFILES=90
if [ ! -n "$1" ]
then
echo "Usage: exifsetMVI srcfile "
return $E_BADARGS
elif [ -f "$1" ]
then
srcfile=${1}; shift
echo Setting all dates on "${srcfile}..."
# Search for EXIF:DateTimeOriginal
setdate=`exiftool -b -r -d "%Y:%m:%d %H:%M:%S" -t -EXIF:DateTimeOriginal "${srcfile}"`
if [ ! -n "${setdate}" -o "${setdate}" = "0000:00:00 00:00:00" ]
then
# EXIF:DateTimeOriginal not found.
echo EXIF:DateTimeOriginal [${setdate}] not found...
# Search for XMP:DateTimeOriginal. Cut out timezone information!!!
setdate=`exiftool -b -r -d "%Y:%m:%d %H:%M:%S" -t -XMP:DateTimeOriginal "${srcfile}" | cut -c1-19`
echo XMP:DateTimeOriginal:[${setdate}] File:[${srcfile}]
fi
if [ ! -n "${setdate}" -o "${setdate}" = "0000:00:00 00:00:00" ]
then
# XMP:CreateDate not found.
echo XMP:DateTimeOriginal [${setdate}] not found...
# Search for -Keys:CreationDate. Cut out timezone information!!!
setdate=`exiftool -b -r -d "%Y:%m:%d %H:%M:%S" -t -Keys:CreationDate "${srcfile}" | cut -c1-19`
echo Keys:CreationDate:[${setdate}] File:[${srcfile}]
fi
if [ ! -n "${setdate}" -o "${setdate}" = "0000:00:00 00:00:00" ]
then
# Keys:CreationDate not found.
echo Keys:CreationDate [${setdate}] not found...
# Search for Quicktime:CreateDate. Cut out timezone information!!!
setdate=`exiftool -b -r -d "%Y:%m:%d %H:%M:%S" -t -Quicktime:CreateDate "${srcfile}" | cut -c1-19`
echo QuickTime:CreateDate:[${setdate}] File:[${srcfile}]
fi
if [ ! -n "${setdate}" -o "${setdate}" = "0000:00:00 00:00:00" ]
then
# QuickTime:CreateDate not found.
echo XMP:DateTimeOriginal [${setdate}] not found...
# Search for XMP:CreateDate. Cut out timezone information!!!
setdate=`exiftool -b -r -d "%Y:%m:%d %H:%M:%S" -t -XMP:CreateDate "${srcfile}" | cut -c1-19`
echo XMP:CreateDate:[${setdate}] File:[${srcfile}]
fi
if [ ! -n "${setdate}" -o "${setdate}" = "0000:00:00 00:00:00" ]
then
# XMP:CreateDAte not found. Neither EXIF:DateTimeOriginal, XMP:DateTimeOriginal, Keys:CreationDate, QuickTime:CreateDate found.
echo XMP:CreateDate [${setdate}] not found... giving up.
return $E_BADFILES
else
#exifsetalldates """${setdate}""" -quickTime:createdate="""${setdate}""" -quicktime:modifydate="""${setdate}""" -api QuickTimeUTC=1 -v2 "${srcfile}"
echo Setting Date:[${setdate}] on File:[${srcfile}]
exiftool -AllDates="""${setdate}""" -Track*Date="""${setdate}""" -Media*Date="""${setdate}""" -Keys:CreationDate="""${setdate}""" -quickTime:createdate="""${setdate}""" -quicktime:modifydate="""${setdate}""" -execute -FileCreateDate="""${setdate}""" -FileModifyDate="""${setdate}""" -execute """-CreateDate<DateTimeOriginal""" """-ModifyDate<DateTimeOriginal""" -execute -quicktime:contentcreatedate="""${setdate}""" -common_args -api QuickTimeUTC=1 -d """%Y:%m:%d %H:%M:%S""" -m -P -overwrite_original_in_place -wm w -v2 """${srcfile}"""
#"""-CreateDate<DateTimeOriginal""" """-FileModifyDate<DateTimeOriginal""" """-ModifyDate<DateTimeOriginal""" -v "$@"
fi
else
echo "Usage: file not found!"
echo "Usage: exifsetMVI srcfile"
return $E_BADFILES
fi
}
export -f exifsetMVI
#------------------------------------------------------------------------------
#==============================================================================
# exifaddsecs()
# - number of seconds to add
# exiftool -overwrite_original_in_place '-DateTimeOriginal+<0:$filesequence' -v *.JPG
#------------------------------------------------------------------------------
function exifaddsecs() {
E_BADARGS=85
E_BADFILES=90
if [ ! -n "$1" ]
then
echo "Usage: exifaddsecs secs_to_add dstfile"
echo "Usage: secs_to_add between 1 and 59 to DateTimeOriginal"
echo "Usage: use exiforiginaldate afterwards as appropriate"
return $E_BADARGS
elif [ "$1" -gt 0 -a "$1" -lt 60 ]
then
secstoadd=${1}; echo $secstoadd
shift
echo Adding "${secstoadd}" to "$@"
# with * it multiplies the filesequence by X seconds... so it is a geometric progression!
# exiftool -overwrite_original_in_place '-datetimeoriginal+<0:0:${filesequence;$_*='$secstoadd'}' -v "$@"
# exiftool -overwrite_original_in_place '-datetimeoriginal+<0:0:${filesequence;$_='$secstoadd'}' -v "$@"
exiftool -overwrite_original_in_place '-datetimeoriginal+<0:0:${filesequence;$_*='$secstoadd'}' -v "$@"
echo "Usage: use exiforiginaldate afterwards as appropriate"
else
echo "Usage: exifaddsecs secs_to_add dstfile"
echo "Usage: secs_to_add between 1 and 59"
echo "Usage: use exiforiginaldate afterwards as appropriate"
return $E_BADFILES
fi
}
export -f exifaddsecs
#------------------------------------------------------------------------------
#==============================================================================
# exifshifthours()
# - number of hours to shift
# exiftool -overwrite_original_in_place '-DateTimeOriginal+=0:0:0 $hours:0:0' -v *.JPG
#------------------------------------------------------------------------------
function exifshifthours() {
E_BADARGS=85
E_BADFILES=90
if [ ! -n "$1" ]
then
echo "Usage: exifshifthours hours_to_shift dstfile"
echo "Usage: hours_to_shift to ADD between -23 and 23 to DateTimeOriginal"
echo "Usage: use exiforiginaldate afterwards as appropriate"
return $E_BADARGS
elif [ "$1" -gt 0 -a "$1" -lt 24 ]
then
hourstoshift=${1}; echo $hourstoshift
shift
echo Shifting POSITIVE "${hourstoshift}" to "$@"
exiftool -overwrite_original_in_place '-datetimeoriginal+=0:0:0 '${hourstoshift}':0:0' -v "$@"
elif [ "$1" -lt 0 -a "$1" -gt -24 ]
then
hourstoshift=`expr -1 \* ${1}`; echo $hourstoshift
shift
echo Shifting NEGATIVE "${hourstoshift}" to "$@"
exiftool -overwrite_original_in_place '-datetimeoriginal-=0:0:0 '${hourstoshift}':0:0' -v "$@"
else
echo "Usage: exifshifthours hours_to_shift dstfile"
echo "Usage: hours_to_shift to ADD between -23 and 23 to DateTimeOriginal"
echo "Usage: use exiforiginaldate afterwards as appropriate"
return $E_BADFILES
fi
}
export -f exifshifthours
#------------------------------------------------------------------------------
#==============================================================================
# exifcopytags()
# - srcfile
# - dstfile
# Copy all metadata from one file to another
# exiftool -TagsFromFile srcimage.jpg "-all:all>all:all" targetimage.jpg
# USE -overwrite_original_in_place in applicable
# USE WITHOUT all:all will copy everything including GPS data (works with MP4)
#------------------------------------------------------------------------------
function exifcopytags() {
E_BADARGS=85
E_BADFILES=90
if [ ! -n "$1" -o ! -n "$2" ]
then
echo "Usage: exifcopytags srcfile dstfile"
return $E_BADARGS
elif [ -f "$1" ]
then
srcfile=${1}; shift
echo Copying all tags from "${srcfile}" to "$@"
exiftool -v -overwrite_original_in_place -TagsFromFile "${srcfile}" "${@}"
else
echo "Usage: file(s) not found!"
echo "Usage: exifcopytags srcfile dstfile"
return $E_BADFILES
fi
}
export -f exifcopytags
#------------------------------------------------------------------------------
#==============================================================================
# exifcleantags()
# - files
# Claen all metadata from one file
# exiftool -overwrite_original -all= -gps:all= *.jpg
# USE -overwrite_original_in_place in applicable
#------------------------------------------------------------------------------
function exifcleantags() {
E_BADARGS=85
E_BADFILES=90
if [ ! -n "$1" ]
then
echo "Usage: exifcleantags files"
return $E_BADARGS
elif [ -f "$1" ]
then
echo Cleaning all tags from "$@"
exiftool -v -overwrite_original -all= -gps:all= "${@}"
else
echo "Usage: file(s) not found!"
echo "Usage: exifcleantags files"
return $E_BADFILES
fi
}
export -f exifcleantags
#------------------------------------------------------------------------------
#==============================================================================
# exifviewdates
# The AllDates tag is designed for common EXIF date/time tags
# (CreateDate, ModifyDate and DateTimeOriginal),
# but MOV/MP4 doesn't support EXIF. Having said this, it does sort of work
# for videos as well, but you may want to target specific video tags.
# You should take a look at what tags already exist in your videos and write
# the ones you think make sense:
#
# See also https://discussions-cn-prz.apple.com/en/docs/DOC-250002750
#------------------------------------------------------------------------------
alias exifviewdates="exiftool -a -G1 -s -api QuickTimeUTC=1 -time:all -api RequestAll=2"
#------------------------------------------------------------------------------
#==============================================================================
# exifviewfaces
# List regions and faces found on pic
#------------------------------------------------------------------------------
alias exifviewfaces="exiftool -a -s -G1 -struct -regioninfo"
#------------------------------------------------------------------------------
#==============================================================================
# exifEqualizeOriginalDate
# - file.txt (generated by exif * > file.txt)
# Find files from a file (generated by the output of exif * > before.txt)
# And equalizes the date to OriginalDate in case there are any differences
# on the dates.
#------------------------------------------------------------------------------
function exifEqualizeOriginalDate () {
E_BADARGS=85
E_BADFILES=90
if [ ! -n "$1" ]
then
echo "Usage: exifEqualizeOriginalDate file.txt"
return $E_BADARGS
elif [ -f "$1" ]
then
# 4 = DateTimeOriginal
# 5 = FileModifyDate
# 6 = CreateDate
# 11>> 12 = ModifyDate - for PXL Phone videos!
# 13>> 14 = QuickTimeCreateDate
# 14>> 15 = QuickTimeModifyDate
# 15>> 16 = KeysCreationDate
# 17 = ContentCreate
# Updated 2022.12.28
# 1.Directory|2.FileName|3.Make%MajorBrand|4.DateTimeOriginal|5.FileModifyDate|6.CreateDate|7.Keywords|8.Subject|9.Orientation|10.QuickTimeRotation|11.Caption-Abstract|12.ModifyDate|13.Description|14.QuickTimeCreateDate|15.QuickTimeModifyDate|16.KeysCreationDate|17.RegionType|18.RegionName|19.Duration|20.ImageSize|21.GPSPosition
echo echo Equalizing dates based on OriginalDate "$@"
awk 'BEGIN { FS="|" ; ct = 0 }
NR != 1 && $4 == "-" && $2~/.*\.(MOV|mov)$/ && $16 != "-" {
printf( "echo MOVIE No Original Date \"%s/%s\" with KeysCreationDate=\"%s\"\n", $1, $2, $16)
fnamedate=substr($2, 5, 4) ":" substr($2, 9, 2) ":" substr($2, 11, 2) " " substr($2, 14, 2) ":" substr($2, 16, 2) ":" substr($2, 18, 2)
printf( "exifKeysdate \"%s/%s\"", $1, $2)
if ( fnamedate != $16 ) {
printf( "; exifrenamefile \"%s/%s\" ; exiforiginaldate \"%s/%s\" ; exifsetMVI \"%s/%s\"\n", $1, $2, $1, $2, $1, $2 )
}
else
printf( "; exiforiginaldate \"%s/%s\" ; exifsetMVI \"%s/%s\"\n", $1, $2, $1, $2 )
next }
NR != 1 && $4 == "-" && $2~/PXL.*\.(MP4|mp4)$/ && $12 != "-" {
# Use exifrecover_modifydate for Pixel phones (PXL) captured video mp4 to get ModifyDate and not FileModifyDate
printf( "echo PIXEL Phone MP4 No Original Date \"%s/%s\" with ModifyDate=\"%s\"\n", $1, $2, $12)
fnamedate=substr($2, 5, 4) ":" substr($2, 9, 2) ":" substr($2, 11, 2) " " substr($2, 14, 2) ":" substr($2, 16, 2) ":" substr($2, 18, 2)
printf( "exifrecover_modifydate \"%s/%s\"", $1, $2)
if ( fnamedate != $5 ) {
printf( "; exiforiginaldate \"%s/%s\" ; exifsetMVI \"%s/%s\"; exifrenamefile \"%s/%s\" \n", $1, $2, $1, $2, $1, $2 )
}
else
printf( "; exiforiginaldate \"%s/%s\" ; exifsetMVI \"%s/%s\"\n", $1, $2, $1, $2 )
next }
NR != 1 && $4 == "-" && $2~/.*\.(MP4|mp4|mov)$/ && $5 != "-" {
printf( "echo MP4 or mov No Original Date \"%s/%s\" with FileModifyDate=\"%s\"\n", $1, $2, $5)
fnamedate=substr($2, 5, 4) ":" substr($2, 9, 2) ":" substr($2, 11, 2) " " substr($2, 14, 2) ":" substr($2, 16, 2) ":" substr($2, 18, 2)
printf( "exifmodifydate \"%s/%s\"", $1, $2)
if ( fnamedate != $5 ) {
printf( "; exiforiginaldate \"%s/%s\" ; exifsetMVI \"%s/%s\"; exifrenamefile \"%s/%s\" \n", $1, $2, $1, $2, $1, $2 )
}
else
printf( "; exiforiginaldate \"%s/%s\" ; exifsetMVI \"%s/%s\"\n", $1, $2, $1, $2 )
next }
NR != 1 && $4 == "-" {
printf( "echo No Original Date \"%s/%s\"\n", $1, $2) ; next }
NR != 1 && ( $4 != $5 || $4 != $6 || $4 != $12 ) {
printf( "exiforiginaldate \"%s/%s\"\n", $1, $2) }
NR != 1 && $2~/(IMG|PXL)_[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])_([01][0-9]|2[0-3])([0-5][0-9]){2}.*$/ {
namedate=substr($2, 5, 4) ":" substr($2, 9, 2) ":" substr($2, 11, 2) " " substr($2, 14, 2) ":" substr($2, 16, 2) ":" substr($2, 18, 2)
if ( namedate != $4 ) {
# print "$4 = [" $4 "] namedate = [" namedate "]"
printf( "exifrenamefile \"%s/%s\"\n", $1, $2)
}
}' "${@}"
else
echo "Usage: file(s) not found!"
echo "Usage: exifEqualizeOriginalDate file.txt"
return $E_BADFILES
fi
}
export -f exifEqualizeOriginalDate
#------------------------------------------------------------------------------
#==============================================================================
# exifsetdatefromname()
# - files
# Command which assigns the date/time to EXIF fields ...
# based on the filename of files sourced original pictures
#------------------------------------------------------------------------------
function exifsetdatefromname() {
E_BADARGS=85
E_BADFILES=90
#echo "${@}"
for a in "${@}"
do
#echo "$a"
xtension="${a##*.}"
fname=`basename "$a" .${xtension}`
if [[ "$fname" =~ (IMG|PXL)_[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])_([01][0-9]|2[0-3])([0-5][0-9]){2}.*$ ]]
then
YYear=`echo "$fname" | cut -c 5-8` ; # echo $YYear
MMonth=`echo "$fname" | cut -c 9-10` ; # echo $MMonth
DDay=`echo "$fname" | cut -c 11-12` ; # echo $DDay
HHour=`echo "$fname" | cut -c 14-15` ; # echo $HHour
MMinute=`echo "$fname" | cut -c 16-17` ; # echo $MMinute
SSecond=`echo "$fname" | cut -c 18-19` ; # echo $SSecond
echo "--- Setting date based on name" fname:"$fname"+"$xtension"="$YYear:$MMonth:$DDay $HHour:$MMinute:$SSecond"
exifsetalldates "\"$YYear:$MMonth:$DDay $HHour:$MMinute:$SSecond\"" "$a"
else
echo "--- Bypassing" fname:"$fname" + xtension:"$xtension"
fi
done
}
export -f exifsetdatefromname
#------------------------------------------------------------------------------