Deleting old backups

Let’s say you have a directory of backups looking like this:

.\
 \-> user1\
          \-> [date1]_[time1]
          \-> [date2]_[time2]
          \-> some more sub directories with date and time in the name
 \-> user2\
          \-> [date3]_[time3]
          \-> [date4]_[time4]
          \-> some more sub directories with date and time in the name
 \-> some more user sub directories

Where [dateN] is the date of the backup starting with a 4 digit year, followed by a two digit month and day, e.g. 20160531.

Now, you run out of disk space and you want to delete the oldest backups, let’s say those from 2015 and 2016. How do you do that?

You could, of course write a program, or, if you are more of a scripting person, a script, that

  1. recurses through the first level of sub directories
  2. looks for sub directories starting with 2015 or 2016
  3. deletes these recursively

Or, you could combine the shell commands find and rm:

find . -maxdepth 2 -mindepth 2 -type d -name "2015*" -exec rm -r {} \;
find . -maxdepth 2 -mindepth 2 -type d -name "2016*" -exec rm -r {} \;

find searches for files and directories that match the given query and does something for each file found, which in this case is call the command rm. But lets have a look at the specific commands above. It restricts the results by the following conditions:

  • “.” (a dot) means: Start in the current directory
  • “-maxdepth 2” means: Recurse sub directories down to two levels maximum
  • “-mindepth 2” means: Recurse sub directories down two levels minimum
  • “-type d” means: Only process directories (not files or devices or links)
  • “-name “2015*”” means: Process only entries whose name matches the shell wildcard “2015*”, so starts with “2015”
  • “-exec rm -r {} \;” means: For each entry execute the command “rm -r {}”, where {} is a place holder for the current entry name.

If you want to test the find command without risking to lose data, leave out the -exec part at the end. The find command will then simply output the entries it finds.

find . -maxdepth 2 -mindepth 2 -type d -name "2015*"