# Bash delete folder if not present in other folder

imaging a folder structure like:

Peter
|- Cats
|- Mini
|- Maunz
|- Tippsi
|– Dogs
|- Brutus

Eva
|- animals
|- Mini
|- Brutus


I'd like to delete all subfolders in Peter/*/ if they not present in Eva/animals/ (Maunz and Tippsi). This is what I have so far. It's working but it feels as my combination of loop and find is not the best solution:

for dir in ./Peter/*/*/
do
dir=${dir%*/} if find './Eva/animals' -type d -name${dir##*/} -exec false {} +
then
echo "${dir%*/} not found and deleted" rm -rf${dir%*/}
fi
done


For learning, can this code be optimized?

find is good for finding files and directories recursively in a filesystem tree. Based on your description and example, you probably don't need that. If you want to check that some directory foo exists directly under /some/path, it's much simpler and more efficient to use the test or [ builtin.

There are some other minor issues in the posted code:

• It's a good practice (and often necessary) to double-quote variables in command parameters. For example instead of rm -rf ${dir%*/} write rm -rf "${dir%*/}"

• Instead of writing ${dir%*/} 3 times, it would be better to store in a variable. In fact you did store the result of the first "call" in a variable, and since subsequent calls on the modified value will be the same, you could have used $dir.

• I think dir=${dir%/} is equivalent to dir=${dir%*/} but simpler.

Putting the above together, a cleaner, more efficient alternative:

#!/usr/bin/env bash

for dir in ./Peter/*/*/
do
dir=${dir%/} name=${dir##*/}
if ! [ -d "./Eva/animals/$name" ] then echo "$dir not found and deleted"
rm -rf "\$dir"
fi
done