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?
1 Answer 1
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%*/}writerm -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 todir=${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