7

I need a command that deletes all files, folders and sub-folders that were not updated longer than 31 days. I tried this one

find . -mindepth 1 -mtime +31 -exec rm -rf "{}" \;

But if I have hierarchy like this

.
├── old_sub_folder1
└── old_sub_folder2
    ├── old_file
    └── old_sub_folder3
        └── new_file

where old_* are old folders\files and new_file is a new file.

This command will delete all contents. Because old_sub_folder2 date was not updated after new_file was created.

I need a command that would not delete old_sub_folder2/old_sub_folder3/new_file

2 Answers2

5

The problem is that you added the -r option to your rm command. This will delete the folders even if they are not empty.

You need to do this in two steps:

  1. Delete only the old files:

    find . -type f -mtime +31 -delete

  2. To delete any old folders, if they are empty, we can take a peek here, and tweak it a bit:

    find . -type d -empty -mtime +31 -delete

0
find  . -type d ! -name . -mtime +31 -exec sh -c '
   case $(find "$1" ! -mtime +31 -exec echo x \; -prune) in
      "" ) rm -rf "$1" || echo "Error could not delete folder \"$1\"" ;;
   esac
' {} {} \;

From the current directory we launch find and look at only directories that have not been updated since the last 31 days. And in each of these directories we in turn dive in and look for anything that is not older than 31 days, and upon finding it we echo a dummy character and also prune any forward search (ideally we should just terminate our search here by means of -quit but that's not POSIX hence we settle for -prune).

Then we look for the result of this find operation and should it turn out to be empty we know that not even one element (file/dir/link/etc.) was new and hence this dir. is safe for deletion.