I found such solutions:

find . -type f ! -newermt '04/29/2018 16:00:00' -exec rm -f {} \;

But I need dynamic dates. I mean not one fixed date, but I'm going to use this script with cron every day and it should remove all files, changed one months before (and more).



According to man find, you can use strings that the date command recognizes.

-newerXY reference

       Succeeds  if  timestamp  X  of the file being considered is 
       newer than timestamp Y of the file reference.  The letters X 
       and Y can be any of the following letters:

       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.

According to man date, you can use human-readable phrases like "a month ago". For more details, see GNU Coreutils Manual: Date input formats.

       The --date=STRING is a mostly free format human readable date
       string  such  as  "Sun,  29  Feb  2004 16:21:42  -0800"  or  
       "2004-02-29 16:21:42" or even "next Thursday".  A date string 
       may contain items indicating calendar date, time of day, time 
       zone, day of week, relative time, relative date, and numbers.   
       An  empty  string indicates the beginning of the day.  The date 
       string format is more complex than is easily documented here but 
       is fully described in the info documentation.

As bac0n notes, you may be interested in find's -delete flag:

       Delete  files;  true if removal succeeded.  If the 
       removal failed, an error message is issued. If -delete 
       fails, find's exit status will be nonzero  (when  it  
       eventually  exits).   Use  of -delete automatically turns 
       on the `-depth' option.

       Warnings:  Don't  forget  that the find command line is 
       evaluated as an expression, so putting -delete first will 
       make find try to delete everything below the starting 
       points you specified. When testing a find command line 
       that you later intend to use with -delete, you should 
       explicitly specify -depth in order to avoid later 
       surprises.  Because -delete  implies  -depth,  you cannot 
       usefully use -prune and -delete together.

       Together  with  the -ignore_readdir_race option, find 
       will ignore errors of the -delete action in the case the 
       file has disappeared since the parent directory was read: 
       it will  not  output an error diagnostic, and the return 
       code of the -delete action will be true.

So the command you need may look something like:

find -type f \! -newermt "last month" -delete
  • 1
    Oops, totally missed it thanks to being way more human readable than expected and not highlighted as code. – val is still with Monica Sep 22 '20 at 16:58
  • 1
    @valsaysReinstateMonica Added an explicit example to the end to tie it together. – xiota Sep 22 '20 at 17:22

You can use

find . -type f -mtime +30 -exec rm -f {} \;

or simpler

find . -type f -mtime +30 -delete

That will delete all files modified more than 30 days ago.


My solution:

find . -type f ! -newermt "$(date -d 'now - 1 month' +'%D %T')" -exec rm -f {} \;
  • 3
    There's no need to call the date command separately. The find command can directly interpret strings recognized by the date command. find ... -newermt "last month" ... would work just as well. – xiota Sep 22 '20 at 9:10
  • 4
    You can use -delete instead of -exec rm ... – bac0n Sep 22 '20 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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