Delete files older than X days +

581,935

Solution 1

Be careful with special file names (spaces, quotes) when piping to rm.

There is a safe alternative - the -delete option:

find /path/to/directory/ -mindepth 1 -mtime +5 -delete

That's it, no separate rm call and you don't need to worry about file names.

Replace -delete with -depth -print to test this command before you run it (-delete implies -depth).

Explanation:

  • -mindepth 1: without this, . (the directory itself) might also match and therefore get deleted.
  • -mtime +5: process files whose data was last modified 5*24 hours ago.

Solution 2

Note that this command will not work when it finds too many files. It will yield an error like:

bash: /usr/bin/find: Argument list too long

Meaning the exec system call's limit on the length of a command line was exceeded. Instead of executing rm that way it's a lot more efficient to use xargs. Here's an example that works:

find /root/Maildir/ -mindepth 1 -type f -mtime +14 | xargs rm

This will remove all files (type f) modified longer than 14 days ago under /root/Maildir/ recursively from there and deeper (mindepth 1). See the find manual for more options.

Solution 3

It's the same. You just have to provide the parent directory rather than the prefix of files. In your example, it would be:

find /path/to -type f -mtime +5 -exec rm {} \;

This will delete all the files older than 5 days which are under /path/to and its sub-directories.

To delete empty sub-directories, refer to @Costas comment above.

Share:
581,935

Related videos on Youtube

John Edgar
Author by

John Edgar

Updated on September 18, 2022

Comments

  • John Edgar
    John Edgar almost 2 years

    I have found the command to delete files older than 5 days in a folder

    find /path/to/files* -mtime +5 -exec rm {} \;
    

    But how do I also do this for subdirectories in that folder?

    • rahul
      rahul about 9 years
      Do you mean files inside the sub directories? or the sub directories themselves?
    • Costas
      Costas about 9 years
      find /path/to -type d -empty -delete
    • John Edgar
      John Edgar about 9 years
      Delete files in subdirectories that are also 5+ days old
    • Jpark822
      Jpark822 about 9 years
      Possibly fun when I have files with spaces. E.g a file called "test one" and rm gets fed rm test one. (Which will delete a file called "test" and a file called "one", but not a file called "test one"). Hint: -delete or -print0
    • Walf
      Walf about 8 years
      As a side note, always quote the argument provided by find to avoid issues with special characters, as mentioned in the answer's first line. E.g.: find /path/to/files/ -exec somecommand '{}' \;
    • Kusalananda
      Kusalananda about 4 years
      @Walf The only reason one would want to quote {} is if one's shell treats that 2-character string specially. I believe (t)csh does this, but no other shell that I know of. You don't have to quote {} in e.g. bash, no matter what filenames you come across. The POSIX standard guarantees that each found pathname will be given to the utility as a separate argument.
    • Walf
      Walf about 4 years
      @Kusalananda or if you're writing a command that may end up getting executed in another shell like fish. Don't make assumptions, better safe than sorry, etc. Makes it obvious that it's an argument to find, like when you have to quote glob patterns inside -name (and related) arguments.
    • Seth Projnabrata
      Seth Projnabrata over 3 years
      The easiest way is the below . You can first check the file names count with the below for the last 2 months , then verify and check , then delete the files . find . -iname ".gz" -mindepth 1 -mtime +60 | wc -l Then check the files find . -iname ".gz" -mindepth 1 -mtime +60 -print Once verified you can delete the same . find . -iname "*.gz" -mindepth 1 -mtime +60 | xargs rm -f
  • Jpark822
    Jpark822 about 9 years
    Note that for each and every file you will execute the rm command. If you have 1000 files older than 5 days then rm will get started 1000 times. For this reason consider the -delete option as in Costa's comment or -exec rm {} \+
  • Oleg
    Oleg over 8 years
    Also use -type f to delete files only (and keep sub directories)
  • zmonteca
    zmonteca about 8 years
    Alternatively, if you want to do the same for all files NEWER than five days: find /path/to/directory/ -mindepth 1 -mtime -5 -delete
  • Cbhihe
    Cbhihe almost 8 years
    Per @AfshinHamedi's answer on AskUbuntu (askubuntu.com/questions/589210/removing-files-older-than-7-‌​day), be careful with files containing newlines and special characters. Instead use find /root/Maildir/ -mindepth 1 -type f -mtime +14 -print0 | xargs -r0 rm --
  • Cbhihe
    Cbhihe almost 8 years
    @Hennes: -- 1) not sure you need to escape + in that case. -- 2) better to write -exec rm '{}' + to fend off the evil of files with special characters (spaces, newlines, etc...) in their name.
  • Dani_l
    Dani_l about 7 years
    Or just add '+' to the find results
  • dokgu
    dokgu about 7 years
    If my path contains spaces how should I do it? find /path/to/dir\ with\ spaces/ -mindepth 1 -mtime +5 -delete?
  • atripes
    atripes over 6 years
    @uom-pgregorio I would suggest putting the path in quotes.
  • Rolf
    Rolf about 6 years
    The timestamp of a folder might be older than the timestamp of file within a subfolder of that folder, i.e. in /a/b/c.txt, c.txt could be young and a old (in terms of mtime). And find could potentially find only one of them (assuming -mindepth is not set). However, -delete will not delete non-empty folders.
  • access_granted
    access_granted almost 6 years
    not on Solaris.
  • access_granted
    access_granted almost 6 years
    find /path/to/directory/ -mtime +5 -exec rm -rf {} \; <<- would be a SunOS version. -mindepth also doesn't work there.
  • Johan
    Johan over 5 years
    Note that every find argument is a filter that uses the result of the previous filter as input. So make sure you add the -delete as the last argument. IE: find . -delete -mtime +5 will delete EVERYTHING in the current path.
  • zyy
    zyy over 4 years
    With option -mmin in place of -mtime, you can specify time in terms of minutes.
  • Kusalananda
    Kusalananda about 4 years
    There is no issue with using -exec rm {} \;. The pathname of the argument will be properly delimited by find, no matter what the filename is. It is not "piping to rm". This answer resolves the issue, not by using -delete, but by using a directory path as the initial search path instead of a bunch of file paths (this is not even mentioned in the answer).
  • João Pimentel Ferreira
    João Pimentel Ferreira about 3 years
    unix find command is indeed a very powerful tool
  • Franchesca
    Franchesca over 2 years
    I found that -delete will work with very large lists of files, whereas -exec rm {} \; can fail if the list of matches is too long.
  • mwfearnley
    mwfearnley over 2 years
    Note that with -exec rm {} +, if there are too many files, rm may complain: Argument list too long. So yes, -delete does seem like the much more sensible option.