I have a backup script that runs once a day. It saves the backups in below the backup folder in a subfolder named by date ($(date +"%F")).

Another script for cleanup is meant to run once a week. I want this script to keep the newest 10 backups and delete all others.

Currently I simply delete everything older than 10 days by calling find $PWD -type d -ctime +10 -exec rm -rf {} +. But this could destroy all backups if there weren't any backups in the last 10 days because of errors that haven't been realized (which should not but may happen).

If the script would keep the number of available backups at 10 or more, nothing (that) dangerous would happen.

So how to keep only the newest x subfolders and delete all others

1 Answer 1


Since your subdirectories are sensibly named, you can delete all but the most recent 10 with:

ls -d */ | head -n-10 | xargs rm -rf

Taking the above command one piece at a time:

  • ls -d */ prints out the subdirectories in alphabetic order. Since your subdirectories are named by date with $(date +"%F"), this is the same as listing from oldest to newest.

  • head -n-10 prints all except for the last ten lines. Thus, this prints all but the ten most recent subdirectories.

  • The command xargs rm -rf will delete all file names that it receives from head -n-10.

When testing this, you may want to try:

ls -d */ | head -n-10 | xargs echo rm -rf

This will show you what rm command would be executed without actually executing it.

The above will not work with subdirectories that have spaces, tabs or newlines in their names.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.