232

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?

8
  • Do you mean files inside the sub directories? or the sub directories themselves?
    – rahul
    Commented Apr 7, 2015 at 16:35
  • 3
    find /path/to -type d -empty -delete
    – Costas
    Commented Apr 7, 2015 at 16:39
  • 2
    Delete files in subdirectories that are also 5+ days old
    – Teddy77
    Commented Apr 7, 2015 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
    Commented Apr 7, 2015 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
    Commented Jun 17, 2016 at 1:54

5 Answers 5

414

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.
13
  • 43
    Also use -type f to delete files only (and keep sub directories)
    – Oleg
    Commented Mar 4, 2016 at 8:44
  • 5
    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
    Commented Apr 19, 2016 at 17:29
  • 3
    @uom-pgregorio I would suggest putting the path in quotes.
    – atripes
    Commented Oct 6, 2017 at 14:40
  • 43
    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
    Commented Jan 1, 2019 at 11:39
  • 6
    With option -mmin in place of -mtime, you can specify time in terms of minutes.
    – zyy
    Commented Jan 30, 2020 at 2:31
23

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.

2
  • 9
    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
    Commented Jul 12, 2016 at 8:17
  • 2
    Or just add '+' to the find results
    – Dani_l
    Commented Apr 2, 2017 at 11:07
13

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.

3
  • 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
    Commented Apr 7, 2015 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
    Commented Jul 12, 2016 at 9:04
  • 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.
    – mwfearnley
    Commented Oct 29, 2021 at 13:48
0

Disclaimer: I'm the current author of rawhide (rh) (see https://github.com/raforg/rawhide).

It probably makes the most sense to delete empty directories after deleting files that are older than X days. The modification time of directories is when entries were added or deleted from them. Deleting old files will update the modification time of the directory that contained them to the time of the deletion. So, you don't want to refer to the modification time of the directories themselves. Just delete empty directories. Deleting files at least 5 days old, and then deleting the resulting empty directories can be done with:

rh -UUU /path/to 'f && old(5*days)
rh -UUU /path/to 'd && empty'

-UUU unlinks/removes/deletes the matching files.

The rest is the search criteria.

f matches regular files.

old(5*days) matches files modified at least 5 days ago.

d matches directories.

empty matches empty directories (and regular files of zero size).

It can also be done with find, of course:

find . -type d -empty -delete

As stated by Costas.

-1
find . -mtime +3 -type f -not -name '*pid*' |xargs rm -rf
1
  • This seems quite unrelated to the question at hand.
    – Kusalananda
    Commented Apr 3, 2020 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .