Back to blog
Jan 2022·1 min readAI-translated

Automatically Rename and Copy GoPro Photos

#bash#dateinamen#gopro#ordnung#sortierung

There is a newer and better version here: Autosort - Sort Photos and Videos Quickly and Easily

Ah yes, the dreaded topic of "GoPro file names". The file names look like a jumble and you can't assign anything to anything. So what to do?

Don't worry - there's a solution in the form of a bash script.

What does it do? Basically, the script checks defined locations for GoPro videos / camera photos (yes, this works for photographers too). When files are found, a subfolder in the format YYYY-MM-DD is created, and the files are copied into that folder following the scheme YYYY-MM-DD-HH-ii-ss.ext. An MP4 video you recorded on 30.01.2022 at 14:44:12 is therefore saved here:

/Volumes/Videos/Videos/2022-01-30/2022-01-30-14-44-12.mp4

If the copy was successful (verified using a hash value), the original is deleted.

You only need to adjust the following paths:

  • video_target = Videos are copied here
  • foto_target = Photos are copied here
  • video_sources = These folders are scanned for videos
  • foto_sources = These folders are scanned for photos
#!/bin/sh
video_target="/Volumes/Videos/Videos/"
foto_target="/Volumes/Extern01/Fotos/"
video_sources=("/Volumes/Untitled/MP_ROOT" "/Volumes/GoPro/DCIM/100GOPRO")
foto_sources=("/Volumes/Untitled/DCIM/100MSDCF" "/Volumes/Untitled/private/AVCHD/BDMV/STREAM")
# FIRST PARAMETER: 0 = KEEP FILE NAME / 1 = RENAME TO DATETIME NAME
docopy(){
num_files=`ls -1q "$1" | wc -l`
filecount=0
for file in $1/*; do
    filecount=$((filecount+1))
    echo "File/Folder #$filecount of $num_files"
    if [[ -d ${file} ]]
    then
      echo "$file is Directory. Check it's subdirectories."
      docopy "$file" $2 $3
    fi
    if [ ! -f "$file" ]; then
        echo "$file does not contain any files. Next."
        continue
    fi
    original_folder_name=`stat -f "%Sm" -t "%Y-%m-%d" "$file"`
    original_file_datetime=`stat -f "%Sm" -t "%Y-%m-%d-%H-%M-%S" "$file"`
    target_path="$2${original_folder_name}/"
    original_file_name=$(basename ${file})
    target_file="$target_path/$original_file_name"
    original_file_extension="${original_file_name##*.}"
    echo "Source: ${file}"
    echo "Destination: ${target_path}"
    echo "Copying..."
    if [ -f "$file" ] && [ -f "$target_path" ];
    then
      md5SrcFile=$(md5 -q "$file")
      md5DstFile=$(md5 -q "$target_file")
      if [ "$md5SrcFile" == "$md5DstFile" ]; then
    echo "The file ${target_path} already exists with MD5 Matching. Skip?"
    read -p "Y to Skip, C to Continue " skip
      fi
    if [ "$skip" == "Y" ]; then
      continue
    fi
    fi
    mkdir -p "${target_path}"
    md5SrcFile=$(md5 -q "$file")
    rsync -ct ${file} ${target_path}
    md5DstFile=$(md5 -q "$target_file")
    if [ "$md5SrcFile" == "$md5DstFile" ] && [ "$md5SrcFile" != "" ] && [ "$md5DstFile" != "" ];
    then
      rm ${file}
    else
      echo "ERROR: MD5 MISMATCH"
      exit
    fi
    if [ $3 -eq 1 ]
    then
    incrementor=0
    renamed_file="$target_path$original_file_datetime.$original_file_extension"
    if [ -f "$renamed_file" ]; then
      incrementor=$((incrementor+1))
      renamed_file="$target_path$original_file_datetime.$incrementor.$original_file_extension"
    fi
      mv $target_file $renamed_file
    fi
    echo "Done"
    echo "___"
  done
}
echo "Scanning default folders."
for i in "${video_sources[@]}"; do
  if [ -d "$i" ] && [ -d $video_target ]; then
    docopy "$i" $video_target  1
  fi
done
for i in "${foto_sources[@]}"; do
  if [ -d "$i" ] && [ -d $foto_target ]; then
    docopy "$i" $foto_target  0
  fi
done
read -p "Do you want to copy files from an individual path? Press Y or N: " tmp
if [ "$tmp" = "Y" ]; then
  read -p "Enter Videos or Photos: " medium
  read -p "Enter Source path: " src
  if [ "$medium" == "Videos" ] && [ -d "$src" ] && [ -d $video_target ]; then
    docopy "$src" $video_target  1
  fi
  if [ "$medium" == "Photos" ] && [ -d "$src" ] && [ -d $foto_target ]; then
    docopy "$src" $foto_target  0
  fi
fi
echo "Finished"
NewerJavaScript - ClosuresOlderC# Delegates