167

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?

  • Do you mean files inside the sub directories? or the sub directories themselves? – rahul Apr 7 '15 at 16:35
  • 3
    find /path/to -type d -empty -delete – Costas Apr 7 '15 at 16:39
  • 2
    Delete files in subdirectories that are also 5+ days old – Teddy291 Apr 7 '15 at 16:46
  • 3
    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 – Hennes Apr 7 '15 at 17:17
  • 6
    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 '{}' \; – Walf Jun 17 '16 at 1:54
285

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).

| improve this answer | |
  • 27
    Also use -type f to delete files only (and keep sub directories) – Oleg Mar 4 '16 at 8:44
  • 3
    Alternatively, if you want to do the same for all files NEWER than five days: find /path/to/directory/ -mindepth 1 -mtime -5 -delete – zmonteca Apr 19 '16 at 17:29
  • 3
    @uom-pgregorio I would suggest putting the path in quotes. – atripes Oct 6 '17 at 14:40
  • 6
    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. – Johan Jan 1 '19 at 11:39
  • 2
    With option -mmin in place of -mtime, you can specify time in terms of minutes. – zyy Jan 30 at 2:31
18

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.

| improve this answer | |
10

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.

| improve this answer | |
  • 4
    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 {} \+ – Hennes Apr 7 '15 at 17:14
  • @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. – Cbhihe Jul 12 '16 at 9:04
-2
find . -mtime +3 -type f -not -name '*pid*' |xargs rm -rf
| improve this answer | |
  • This seems quite unrelated to the question at hand. – Kusalananda Apr 3 at 15:50

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