Bash: Delete files modified between two dates

I have a long list of backup files created every day, running into Gigabytes. I wanted a way to preserve backup copies as a sample, leaving behind files created on the 1st and 16th of each month, deleting everything else to free up disk space.

I came up with the following:

First delete files between 2nd and 15th of November:
Check that the list is correct:

find backups/*bz2 -newermt "2013-11-02" ! -newermt "2013-11-16" -exec ls -lh {} \; | less

Now delete them:

find backups/*bz2 -newermt "2013-11-02" ! -newermt "2013-11-15" -exec rm {} \;

Then, delete files between 17nd and 30th of November:

find backups/*bz2 -newermt "2013-11-17" ! -newermt "2013-11-30" -exec ls -lh {} \; | less
find backups/*bz2 -newermt "2013-11-17" ! -newermt "2013-11-30" -exec rm {} \; | less

When the -newermt is used, find searches for modification time newer than the time string specified. The ! -newermt acts as the delimiter to mark the end point.

As an example,

find backups/*bz2 -newermt "2013-12-01" ! -newermt "2013-12-03" -exec ls -lh {} \;

finds all files newer than 12 AM on 1st December, and not newer than 12 AM on 3rd December. In other words, it includes files modified on 1st and 2nd of December.

Never use find backups/ instead of find backups/*bz2. This is because the first match is the directory itself, and find lists everything in that directory.

From the man pages for find:

-newerXY reference
Compares the timestamp of the current file with reference. The reference argument is normally the name of a file (and one of its timestamps is used
for the comparison) but it may also be a string describing an absolute time. X and Y are placeholders for other letters, and these letters select
which time belonging to how reference is used for the comparison.

a The access time of the file reference
B The birth time of the file reference
c The inode status change time of reference
m The modification time of the file reference
t reference is interpreted directly as a time

Some combinations are invalid; for example, it is invalid for X to be t. Some combinations are not implemented on all systems; for example B is not
supported on all systems. If an invalid or unsupported combination of XY is specified, a fatal error results. Time specifications are interpreted
as for the argument to the -d option of GNU date. If you try to use the birth time of a reference file, and the birth time cannot be determined, a
fatal error message results. If you specify a test which refers to the birth time of files being examined, this test will fail for any files where
the birth time is unknown.

So a solution which deletes all files except those on the 1st and 15th of October:

find backups/ -newermt "2013-10-02" ! -newermt "2013-10-15" -exec rm {} \;
find backups/ -newermt "2013-10-16" ! -newermt "2013-11-01" -exec rm {} \;

As a general rule, the start date of the wipe will be the day which falls next to the one you want to preserve, and the end date is the date of the next day you want to preserve.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.