Skip to content

Instantly share code, notes, and snippets.

@1nVitr0
Last active April 10, 2022 21:01
Show Gist options
  • Save 1nVitr0/3c36077102def8aa0d839d29149941cb to your computer and use it in GitHub Desktop.
Save 1nVitr0/3c36077102def8aa0d839d29149941cb to your computer and use it in GitHub Desktop.
Shell Script for automatically creating file collections, e.g. for games
# Shell script for automatically creating file collections
# initally written to reduce the number of games when downloading
# retropie rom collections
#!/bin/bash
version="0.3.1"
collection=()
collectionname=""
collsize=0
count=1
breakchars=("(" "." "," ")" "[" "]")
silent=0
verbose=0
case=1
format=".*"
dirs=0
minLength=1
minSize=2
prefix=""
postfix=""
parentDir=""
excludes=""
version()
{
echo "Autocollection tool by Aram Becker - Version $version"
}
usage()
{
version
echo "Usage: autocollection [OPTION]... [DIRECTORY]"
echo
echo "Option -c | --create-dirs must be set to actually collect files, if not set collections are only displayed, not created"
echo
echo "Options:"
echo
echo "-V, --version display version and exit"
echo "-h, --help display this help page and exit"
echo "-f, --format FORMAT set file ending of files to autocollect (e.g. '.nes')"
echo "-c, --create-dirs actually create directories"
echo "-s, --silent don't display collections"
echo "-v, --verbose display all files put into collections"
echo " --prefix PREFIX prefix all collections with given value"
echo " --postfix POSTFIX append all collections with given value"
echo " --min-name-length INT minimum name length of collection"
echo " --min-coll-size INT minimum collection size to be created"
echo "-e, --exclue exclude specific collection names (e.g. 'super,space') to prevent too large collections, comma seperated"
echo "-i, --case-insensitive collect file names without caring about case (e.g. 'Game' and 'game')"
echo "-r, --revert move all games out of their collections back into the folder"
echo "-a, --sort-alphabet Create alphabetical collections"
}
alphabeticFolders()
{
alphabet=("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z")
for c in ${alphabet[@]}
do
files=()
count=0
for f in $c*
do
if [ "$f" != "$c*" ] && [ "$f" != "$c" ]
then
files[${#files[@]}]="${f##*/}"
((count++))
fi
done
for f in ${c,,}*
do
if [ "$f" != "${c,,}*" ]
then
files[${#files[@]}]="${f##*/}"
((count++))
fi
done
if [ ${#files[@]} -gt 0 ]
then
if [ $silent -lt 1 ]
then
echo "Creating directory for $c..."
fi
mkdir "$c"
for (( i=0; i<$count; i++ ))
do
if [ $verbose -gt 0 ]
then
echo "Moving ${files[i]}..."
fi
mv "${files[i]}" "$c"
done
fi
done
}
isBreakChar()
{
retval=0
if [ "$1" = "" ] || [ "$1" = " " ]
then
retval=1
else
for c in ${breakchars[@]}
do
if [ "$1" = "$c" ]
then
retval=1
break
fi
done
fi
echo $retval
}
checkExcluded()
{
retval=0
for key in "${excludes[@]}"
do
if [ "${1,,}" = "${excludes[$key]}" ]
then
retval=1
break
fi
done
echo $retval
}
saveCollection()
{
paren_open=0
for (( i=0; i<${#collectionname}; i++ ))
do
c="${collectionname:$i:1}"
if [ "$c" = "(" ]
then
paren_open=$i
fi
if [ "$c" = ")" ]
then
paren_open=0
fi
done
if [ $paren_open -gt 1 ]
then
collectionname="${collectionname:0:paren_open}"
fi
while [ "${collectionname:((${#collectionname}-1)):1}" = " " ] || [ "${collectionname:((${#collectionname}-1)):1}" = "-" ]
do
collectionname="${collectionname:0:((${#collectionname}-1))}"
done
if [ $case -lt 1 ]
then
collectionname=($collectionname)
collectionname="${collectionname[@]^}"
fi
collectionname="$prefix$collectionname$postfix"
if [ $silent -lt 1 ]
then
echo Creating collection \"$collectionname\" with $collsize entries...
if [ $verbose -gt 0 ]
then
echo "Entries: ${collection[0]}"
for (( j=1; j<$collsize; j++ ))
do
echo " ${collection[j]}"
done
fi
fi
if [ $dirs -gt 0 ]
then
mkdir "$collectionname"
for (( j=0; j<$collsize; j++ ))
do
mv "${collection[j]}" "$collectionname"
done
fi
}
createCollections()
{
for f in *$format
do
fn="${f##*/}"
if [ $case -lt 1 ]
then
fn="${fn,,}"
fi
if [ $collsize -lt 1 ]
then
collectionname="$fn"
collection[0]="${f##*/}"
collsize=1
else
for ((i=0; i<${#fn}; i++))
do
if [ "${fn:$i:1}" = "${collectionname:$i:1}" ]
then
:
else
fulltitle=$(isBreakChar ${fn:((i-1)):1})
if [ "$excludes" = "" ]
then
isExluded=0
else
tempcollname="${fn:0:$i}"
paren_open=0
for (( i=0; i<${#tempcollname}; i++ ))
do
c="${tempcollname:$i:1}"
if [ "$c" = "(" ]
then
paren_open=$i
fi
if [ "$c" = ")" ]
then
paren_open=0
fi
done
if [ $paren_open -gt 1 ]
then
tempcollname="${tempcollname:0:paren_open}"
fi
while [ "${tempcollname:((${#tempcollname}-1)):1}" = " " ] || [ "${tempcollname:((${#tempcollname}-1)):1}" = "-" ]
do
tempcollname="${tempcollname:0:((${#tempcollname}-1))}"
done
isExluded=$(checkExcluded $tempcollname)
fi
if [ $i -gt $minLength ] && [ $fulltitle -gt 0 ] && [ $isExluded -lt 1 ]
then
collectionname="${fn:0:$i}"
collection[$collsize]="${f##*/}"
((collsize++))
else
if [ $collsize -ge $minSize ]
then
saveCollection
fi
collection=()
collectionname="$fn"
collection[0]="${f##*/}"
collsize=1
fi
break
fi
done
fi
((count++))
echo -ne Processed $count files...\\r
done
if [ $collsize -gt $minSize ]
then
saveCollection
fi
}
revert()
{
for dir in */
do
if [ $silent -lt 1 ]
then
echo Unpacking collection ${dir::-1}...
if [ $verbose -gt 0 ]
then
firstline=1
for f in "$dir"/*
do
if [ $firstline -gt 0 ]
then
echo "Entries: ${f##*/}"
firstline=0
else
echo " ${f##*/}"
fi
done
fi
fi
mv "$dir"* .
rm "$dir" -R
done
}
doRevert=0
doAlphabetical=0
while [ "$1" != "" ]; do
case $1 in
-h | --help ) usage
exit
;;
-V | --version ) version
exit
;;
-f | --format ) shift
format=$1
;;
-c | --create-dirs ) dirs=1
;;
-s | --silent ) silent=1
;;
-v | --verbose ) verbose=1
;;
--prefix ) shift
prefix=$1
;;
--postfix ) shift
postfix=$1
;;
--min-name-length ) shift
minLength=$1
;;
--min-coll-size ) shift
minSize=$1
;;
-e | --exclude ) shift
IFS=,
excludes=(${1,,})
;;
-i | --case-insensitive ) case=0
;;
-r | --revert ) doRevert=1
;;
-a | --sort-alphabet ) doAlphabetical=1
;;
* ) if [ "$parentDir" = "" ]
then
parentDir=$1
else
usage
exit 1
fi
esac
shift
done
cd "$parentDir"
version
if [ $doRevert -gt 0 ]
then
echo "reverting collections in $PWD..."
revert
exit
fi
if [ $doAlphabetical -gt 0 ]
then
echo "Creating alphabetical collections in $PWD..."
alphabeticFolders
exit
fi
echo "Creating collections in $PWD..."
echo
createCollections
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment