Ubuntu – Remove files and directories but exclude all files from paths in a text file

command linersync

As per this question and answer:
remove file but exclude all files in a list

This code does exactly what I need, apart from it doesn't work on sub directories.

for i in *; do
    if ! grep -qxFe "$i" filelist.txt; then
        echo "Deleting: $i"
        # the next line is commented out.  Test it.  Then uncomment to removed the files
        # rm "$i"
    fi
done

It appears to just match on text in the text file rather than see each new line as a path. So, when the text file contains:

./leaveme.jpg
./i am staying.gif
./james/leaveme.gif
./james/

It still tries to delete the james directory? It also ignores any other files in the james directory which should be deleted.

Is there any way of getting it to recognise full paths in the text file? I have thousands of sub directories so running this script on each individual directory would take forever.

Best Answer

try using rsync with the help of its exclude option as following:

rsync --dry-run -v -r --remove-source-files \
      --exclude-from='/path/to/excludefile.txt' /path/to/source/ /path/to/somewhere/to_delete

notes:

  • the command is running in --dry-run mode; remove it to take real action.
  • before running, make sure your excludefile.txt is located out of /path/to/source path, or add itself to excludefile.txt file to exclude that also from deleting too.
  • rsync cannot remove empty directories if there was any after operation completed, so you will need delete them manually, try

    find /path/to/source -type d -empty -ok rmdir {} \;
    

    change command to below if you don't want confirm for deletion for each directory.

    find /path/to/source -type d -empty -delete
    
  • see here for demo run added

  • and last step, double check the files&directories moved to /path/to/somewhere/to_delete and then delete the entire directory if you were happy with result.

    \rm -rfi /path/to/somewhere/to_delete  # -i switch is used for confirmation, remove it if you don't needed