Delete folders which not match a list
Assuming your file names do not contain any of :\[*?
, you could still use GLOBIGNORE
. Just format your list of directories accordingly. For example:
$ cat names.txt
folder1
folder3
That is very easy to transform into a colon separated list:
$ paste -s -d : names.txt
folder1:folder3
So, you can now set that as the value of GLOBIGNORE:
GLOBIGNORE=$(paste -s -d : ../names.txt)
And proceed to delete them normally:
rm -r -- *
I just tested this on Linux with 300 directories and it worked perfectly.
Another solution that matches begin and end of the folder names:
IFS=$'\n'
folders="""folder1
folder2"""
for folder in *; do
found=0
if [ -d "$folder" ]; then
for i in $folders; do
if [ $(echo "$folder" | grep -c -E "^$i\$") -eq 1 ]; then
found=1
fi
done
if [ $found -ne 1 ]; then
echo "$folder found and deleted."
rm -rf "$folder"
fi
fi
done
A simple approach is to list all files and ignore the ones that are in the list file. Note that I arrange for the variable ignore_list
to start and end with a newline, so that I can check if $x
is included in a simple way (just checking that $ignore_list
contains $x
doesn't work, since it would also match files whose name is a substring of an element of the ignore list).
newline='
'
ignore_list="$newline$(cat list.txt)$newline"
cd target_folder
for x in * .[!.]* ..?*; do
case "$x" in *"$newline"*) continue;; esac # sanity check: if the file name contains a newline, leave it alone
case "$ignore_list" in
*"$newline$x$newline"*) echo "Skipping $x";;
*) rm -rf -- "$x";
esac
done