Skip to content

Instantly share code, notes, and snippets.

@jivanpal
Last active February 13, 2024 19:10
Show Gist options
  • Select an option

  • Save jivanpal/116032ab6329fa5eaef88c9e9f46f2a3 to your computer and use it in GitHub Desktop.

Select an option

Save jivanpal/116032ab6329fa5eaef88c9e9f46f2a3 to your computer and use it in GitHub Desktop.
Bash scripts to reorganise Google Photos exports from Google Takeout
#!/bin/bash
## Works with the Google Takeout format from 2020 and earlier, in which
## items are already within directories of the form "YYYY-MM-DD", and you
## want a directory hierarchy of the form "YYYY/MM/DD".
##
## You must run this script from the directory which contains all the
## directories of the form "YYYY-MM-DD". The resulting directories of the
## form "YYYY/MM/DD" will be created in this same location.
trap '>&2 echo Interrupted. && exit 1' SIGINT
if [ "$1" = "-n" ] || [ "$1" = "--dry-run" ]; then
maybe_echo='echo'
else
maybe_echo=''
fi
for dir in ????-??-??*/ ; do
year="$( echo "$dir" | grep -Po '^[0-9]{4}' )"
month="$( echo "$dir" | grep -Po '(?<=^[0-9]{4}-)[0-9]{2}' )"
rest="$( echo "$dir" | grep -Po '(?<=^[0-9]{4}-[0-9]{2}-).*(?=/$)' )"
$maybe_echo mkdir -p "$year/$month"
$maybe_echo mv "$dir" "$year/$month/$rest"
done
#!/bin/bash
## Works with the Google Takeout format from 2021 and later, in which
## items are all in a single directory (no timestamp necessarily in file
## or directory names), but JSON files contain Unix timestamps, and you
## want a directory hierarchy of the form "YYYY/MM/DD".
##
## You must start with all items in a folder called `undated`, and run this
## script from its parent. A folder called `dated` will then be created with
## the "YYYY/MM/DD" hierarchy within it. This will leave all files which we
## cannot sort in the `undated` directory for you to sort yourself.
trap '>&2 echo Interrupted. && exit 1' SIGINT
OLDIFS=$IFS
IFS=$'\n'
cd undated
for j in *.json; do
unix_timestamp="$( \
(grep -EA1 photoTakenTime "$j" || >&2 echo "No photoTakenTime in $j") \
| (grep -E timestamp || >&2 echo "No timestamp in $j") \
| sed -E 's/ +/ /g' | sed -E 's/(^ | $)//g' \
| cut -d' ' -f2 \
| (grep -E '^\"[0-9]*\",$' || >&2 echo "Timestamp not in expected format in $j") \
| sed -E 's/^\"([0-9]*)\",$/\1/' \
)"
date="$(date -d "@$unix_timestamp" +%Y/%m/%d)"
basename="$(echo "$j" | grep -Eo '^[^\.]*')"
destination="../dated/$date"
mkdir -p "$destination"
mv "$basename".* "$destination/"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment