#!/bin/bash #$Id: sortvideos,v 2.1 2026/01/31 07:04:03 RogerSeguin Exp $ ######################################################################## # Copyright (c) 2026 Roger Seguin # https://frogzie.duckdns.org # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ######################################################################## # Extract the creation date of the indicated videos and order them chronologically declare -r argv0=$(basename $0) function usage() { local prg=$argv0 cat << :end: $prg - List/rename videos sorted by creation date Usage: $prg [-l | --list] [-r | --rename] videos... Options -l list videos by chronological order (default) -r prefix file names with timestamp Examples $prg --list *.mp4 # List videos in chronlogical order $prg --rename *.mp4 # Prefix video names with timestamp :end: exit 1 } # Scan command line declare -r coptions=$(getopt -o 'hlr' --long 'help,list,rename' -n 'parse-options' -- "$@") [ $? -eq 0 ] || { echo "Failed parsing options." >&2 exit 2 } eval set -- "$coptions" declare -i action=0 # List (0) or rename (1)? while true; do case "$1" in -h | --help) usage ;; -l | --list) action=$((action|1)) shift continue ;; -r | --rename) action=$((action|2)) shift continue ;; -- ) shift break ;; *) echo 'Internal error!' >&2 exit 4 ;; esac done [ $# -eq 0 ] && usage # List videos sorted according to their creation times function listVideos() { local -i count=0 for f in "$@"; do [ -f "$f" ] || continue echo $(exiftool -time:ALL -d '%Y-%m-%d %H:%M:%S' "$f" | grep 'Media Create Date' | awk '{print $5 " " $6}') $f done | sort | while read ff; do count=$((count+1)) printf "%03d " $count echo $ff done return $? } # Rename videos adding a timestamp "yyyymmdd-HHMMSS-" prefix and convert file extension to lower cases function processFilename() { local tim="$1" local src="$2" local dir="$(dirname $src)" local bas="$(basename $src)" local b="${bas%.*}" # Filename stem [ "$bas" != "$b" ] && { local e="${bas##*.}" # File extension bas="$b.${e,,}" # ... converted to lower cases } local dst="$dir/${tim}-${bas}" mv -f "$src" "$dst" [ $((action&1)) -eq 1 ] && echo "$dst" } function renameVideos() { local -i count=0 for f in "$@"; do [ -f "$f" ] || continue echo $(exiftool -time:ALL -d '%Y%m%d-%H%M%S' "$f" | grep 'Media Create Date' | awk '{print $5 " " $6}') $f done | sort | while read ff; do count=$((count+1)) [ $((action&1)) -eq 1 ] && printf "%03d " $count processFilename $ff done return $? } # main() case $action in 0|1) listVideos "$@" ;; 2|3) renameVideos "$@" ;; *) echo "Unknown error" 1>&2 exit 8 ;; esac exit $?