Skip to content

Instantly share code, notes, and snippets.

@drewreece
Last active March 8, 2020 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drewreece/7725253 to your computer and use it in GitHub Desktop.
Save drewreece/7725253 to your computer and use it in GitHub Desktop.
Find all iOS apps in a directory and remove duplicates with the same file name
#!/bin/sh
#
# NOTE: uses sudo to access the protected Time Machine data.
#
# Backup-iOS-Apps.sh
#
# Find all '.ipa' apps in a directory
# Copies found apps to a destination folder. The destination will contain a date stamped folder of Apps
# e.g. condenses iOS apps within Time Machine backups into individual app versions and copies in one folder.
#
# Takes advantage of the file name which includes the version string in iOS apps
# Remove duplicates with the same name (i.e. can parse TimeMachine disk into single app versions)
# Copies found apps to destination folder
# The destination will contain a date stamped folder of Apps
#
# IMPORTANT! Needs sudo (for copy & reading into TM file paths) - RUN IN AN ADMIN ACCOUNT
#
# NOTE all users within Time Machine disk will be stored in the final copy.
# The first users copy will be the one copied
#
#
# USAGE:
# Edit below the PROCESSING BEGINS HERE section
#
#
## @TODO fix paths with plus
##-->> ERROR: Source path is empty for Converter+ 2.3.1.ipa
##-->> ERROR: Source path is empty for UPnP++ 2.1.2.ipa
##
###############################################################################
## CONFIG
###############################################################################
# Save the found file lists to temp-dir/backup-ios-apps
OUTPUTDIR="${TMPDIR}/backup-ios-apps"
# list of file paths (this may contain duplicatess)
LIST="${OUTPUTDIR}/backup-ios-apps-list"
# list of uniq filenames
FILENAMES="${LIST}-filenames"
# list of sorted filenames
SORTED="${LIST}-sorted"
NOW=`date +%Y-%m-%d`
# create temp directory
mkdir -p "${OUTPUTDIR}"
###############################################################################
## GETAPPS FUNCTION
###############################################################################
# Usage:
# getapps "source" "dest"
# will copy apps to dest unless ditto & chown is commented out below
#
getapps() {
source="${1}"
dest="${2}/${NOW}"
# create dest folder with date
mkdir -p "${dest}"
# do we have valid folder paths?
if [[ -d "${source}" && -d "${dest}" ]]; then
echo "-->> Processing: ${source}"
echo "-->> Search for .ipa's in: ${source}"
# make list of found .ipa files
sudo -p "Please enter admin password :" find "${source}" -name *.ipa > "$LIST"
# NOTE: mdls -onlyin "${source}" "kMDItemKind == '*iOS App*'" Is faster but Time Machine volumes are not Spotlight indexed
echo "-->> List created, sorting and finding unique app versions..."
# sort oldest first - keep this to use for moving
sort "${LIST}" > "${SORTED}"
# parse filenames from paths into a list of filenames
cat "${SORTED}" | awk -F '/' '{ printf $NF;$NF = "" ;printf"\n" }' | sort -u > "${FILENAMES}"
# Process using the list of unique filenames
while read word
do
export word="${word}"
# find the first occurrence of the file path in the sorted list
path=$(grep -m 1 "$word" "${SORTED}")
# only copy non-existing files
if [[ ! -f "${dest}/${word}" ]]; then
if [[ -z "${path}" ]]; then
echo "-->> ERROR: Source path is empty for ${word}"
else
echo "-->> Copying: $word"
sudo ditto "${path}" "${dest}"
# change owner to current user (in case other users apps have been copied e.g Time Machine)
sudo chown ${UID} "${dest}/${word}"
fi
else
echo "-->> Skipping existing app: $word"
fi
done < "${FILENAMES}"
fi
}
###############################################################################
## PROCESSING BEGINS HERE - edit the function call(s)
###############################################################################
# Call the getapps function with two folder paths, the source & the destination.
# getapps "source" "dest"
#
# Get current user iTunes apps
getapps "${HOME}/Music/iTunes/iTunes Music" "/Volumes/Backup/iTunes App Purchases"
# Time Machine - takes ages - Disable Time Machine manually first !
echo "-->> Disable Time Machine manually"
echo "-->> It will take a long time to find on large backups..."
getapps "/Volumes/Time Machine" "/Volumes/Backup/iTunes App Purchases"
###############################################################################
# cleanup the temp files
rm -rf "${OUTPUTDIR}"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment