Last active
November 1, 2020 14:34
-
-
Save dmarcelino/5a5f97f8311fc605a741ef4f3b4c95d9 to your computer and use it in GitHub Desktop.
Reduce the number of folders taken by a music collection to please some car head units
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Some car head units have restrictions on the number of folders they can access, | |
# this scripts aims to reduce the number of folders taken by a music collection. | |
# Assumes the music collection is set up as Artist / Album | |
# This also ensures the folders and files don't exceed the maximum file size. | |
# My own head unit restrictions: 255 folders, folder/filename size: 63 chars | |
export MAX_FILE_SIZE=63 | |
export APPLY_CHANGES=false | |
# flatten dir by concatenating parent dir name with dir name | |
flatten_dir() { | |
dir=$1 | |
new_dir=`sed 's/\(.*\)\//\1_/' <<< "$dir"` | |
echo "mv \"$dir\" \"$new_dir\"" | |
if [ "$APPLY_CHANGES" = true ] ; then | |
mv "$dir" "$new_dir" | |
fi | |
} | |
export -f flatten_dir | |
# if artist folder has single album plus loose mp3s, move the mp3s to album folder | |
move_mp3_to_subdir() { | |
dir=$1 | |
subdirs_count=`find "$dir" -depth 1 -type d | wc -l | tr -d "[:blank:]"` | |
if [ "$subdirs_count" -ne 1 ]; then | |
return 0 | |
fi | |
subdir=`find "$dir" -type d -depth 1 -print -quit` | |
if [ "$APPLY_CHANGES" = true ] ; then | |
find "$dir" -iname '*.mp3' -depth 1 -print -exec mv "{}" "$subdir" \; | |
else | |
find "$dir" -iname '*.mp3' -depth 1 -exec echo "mv \"{}\" \"$subdir\"" \; | |
fi | |
} | |
export -f move_mp3_to_subdir | |
shorten_name() { | |
name=$1 | |
name_size=`wc -c <<< "$name" | tr -d "[:blank:]"` | |
if [ "$name_size" -le "$MAX_FILE_SIZE" ]; then | |
return 0 | |
fi | |
ext=${name#"${name%.[^\ ]*}"} | |
echo "[$name_size] mv \"$name\" \"${name:0:MAX_FILE_SIZE-1-${#ext}}${ext}\"" | |
if [ "$APPLY_CHANGES" = true ] ; then | |
mv "$name" "${name:0:MAX_FILE_SIZE-1-${#ext}}${ext}" | |
fi | |
} | |
export -f shorten_name | |
# for mp3s in CD/Disk folder inside album, move them above to the album folder | |
rename_mp3_and_move_above() { | |
dir=$1 | |
disk_number=`basename "$dir" | tr -dc '0-9'` | |
disk_int=`expr $disk_number + 0` | |
if ((disk_int < 1 || disk_int > 99)); then | |
return 0 | |
fi | |
if [ "$APPLY_CHANGES" = true ] ; then | |
find "$dir" -iname '*.mp3' -depth 1 -print -execdir mv "{}" "../$disk_number{}" \; | |
else | |
find "$dir" -iname '*.mp3' -depth 1 -execdir echo "mv \"{}\" \"../$disk_number{}\"" \; | |
fi | |
} | |
export -f rename_mp3_and_move_above | |
execute_operations() { | |
echo | |
echo "Delete non mp3/wma files:" | |
if [ "$APPLY_CHANGES" = true ] ; then | |
find . -type f -not -iname '*.mp3' -not -iname '*.wma' -not -path '*/\.*' -print -delete | |
else | |
find . -type f -not -iname '*.mp3' -not -iname '*.wma' -not -path '*/\.*' -print | |
fi | |
echo | |
echo "Move loose mp3s to subdirectories:" | |
find . -type d -depth 1 -exec bash -c 'move_mp3_to_subdir "$1"' _ {} \; | |
echo | |
echo "Move mp3s in CD/Disk folder to album folder:" | |
find . -type d -depth 3 -regex '.*[^/]*[0-9][^/]*' -exec bash -c 'rename_mp3_and_move_above "$1"' _ {} \; | |
echo | |
echo "Flatten Directories:" | |
find ~+ -type d -depth 2 -exec bash -c 'flatten_dir "$1"' _ {} \; | |
echo | |
echo "Shorten filenames:" | |
find . -not -path '*/\.*' -regex ".*[^/]\{$MAX_FILE_SIZE,\}" -execdir bash -c 'shorten_name "$1"' _ {} \; | |
echo | |
echo "Delete empty folders:" | |
if [ "$APPLY_CHANGES" = true ] ; then | |
find . -type d -empty -print -exec rmdir "{}" \; | |
else | |
find . -type d -empty -print | |
fi | |
} | |
echo "Working dir: $PWD" | |
echo | |
echo "Total dirs before changes: `find . -type d | wc -l | tr -d "[:blank:]"`" | |
echo | |
echo "Calculating changes:" | |
execute_operations | |
read -p "Apply the above changes? [Y/n]" -n 1 -r | |
echo | |
if [[ ! $REPLY =~ ^[Y]$ ]]; then | |
exit 0 | |
fi | |
export APPLY_CHANGES=true | |
execute_operations | |
echo | |
echo "Total dirs after changes: `find . -type d | wc -l | tr -d "[:blank:]"`" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment