Subscribe to How-To Geek

Delete Files Older Than x Days on Linux

The find utility on linux allows you to pass in a bunch of interesting arguments, including one to execute another command on each file. We’ll use this in order to figure out what files are older than a certain number of days, and then use the rm command to delete them.

Command Syntax

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

Note that there are spaces between rm, {}, and \;

Explanation

  • The first argument is the path to the files. This can be a path, a directory, or a wildcard as in the example above. I would recommend using the full path, and make sure that you run the command without the exec rm to make sure you are getting the right results.
  • The second argument, -mtime, is used to specify the number of days old that the file is. If you enter +5, it will find files older than 5 days.
  • The third argument, -exec, allows you to pass in a command such as rm. The {} \; at the end is required to end the command.

This should work on Ubuntu, Suse, Redhat, or pretty much any version of linux.

| More
This article was originally written on 02/21/07 Tagged with: Solaris, Suse Linux, Ubuntu

Daily Email Updates

You can get our how-to articles in your inbox each day for free. Just enter your name and email below:


Name:
Email:

Comments (34)

  1. Ryan

    How about just using the -delete flag rather than the -exec ?

  2. Geo

    “How about just using the -delete flag rather than the -exec ? ”

    Because if you have MANY files you will get maximum arguments exceeded..

    so instead by doing exec you fork one process of rm per result… hope it helps

  3. milkmood

    GOOD STUFF. Dead simple, and prevented me from having to try and write a complex script that would take me days. Implemented this in crontab in 5 minutes.

    HUGE THANKS!

  4. milkmood

    Now, can I pipe the results to a log file in the same line?

  5. Takoro

    >>Now, can I pipe the results to a log file in the same line?

    Yes:

    bash -c ‘date;find /path/to/files* -mtime +5 -exec rm -v {} \;;date’ > ~/mylog

    This way, you’ll get a line at top with the date the line is executed (also a line at the bottom).

    The last two semicolons are necessary, one is for find and one for bash.

  6. pierissimo

    there is an argument for find,so that also directory will be removed?

  7. Artem Russakovskii

    Pierissimo, well, the find command doesn’t care if it’s a file or a directory, so it’ll delete both.

    The above article mentions it “This can be a path, a directory, or a wildcard as in the example above.” but in order to force delete the dirs, you need to do ‘rm -fr’ instead of just ‘rm’. -f will force deletion and -r will do it recursively on all subdirs.

    find can accept a -type argument where ‘find -type f’ will only find files, ‘find -type d’ will find dirs, and ‘find -type l’ will find links.

  8. Train

    Outstanding. Thanks for the help!!! This worked wonderfully!!!

  9. fabry

    this is great.. I have used this like this:
    find /tmp/ -type f -mmin 30 -exec rm {} \;

    to remove files that have been modified from 30 minutes ago.

    mtime remove files n*24 hours old, mmin n minutes old (where n is the number that you pass after the parameter mmin or mtime)

    again, thank you. your hint saved me a bunch of time.

  10. fischer

    This seems to need user input to delete the files, what is the switch to have it delete automatically?

  11. e_sandrs

    As mentioned, adding -f forces the delete.

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

  12. fischer

    But when I run it, it still asks if I want to delete and I must type in a “y”

  13. Bob

    @fischer: The behavior of your rm command is unusual. Normally it will quietly delete unless you tell it otherwise with the “-i” option. There often is a shell alias defined in .bashrc or somewhere similar that replaces “rm” automatically with “rm -i”. It is possible that it will even replace “rm -f” for you. Overall it depends on the shell you use and if your distro has fiddled with the rm command. The behavior of your rm command is unusual.

  14. Ed

    I had an issue like that with the cp command. Ended up that a previous admin had aliased the cp command to ‘cp -i’

  15. Steve

    The simplest general solution to avoid alias issues in scripts, at jobs, etc is to use the full path to the program unless it is a shell primitive, e.g. /bin/rm instead of rm. This also protects you from certain types of malicious trickery.

  16. Karsten

    works like a charm!

    I changed it to allow moving instead of deleting

    find /path/test-source/* -mtime +30 -exec mv {} /path/test-mv-to/ \;

    Tested without using ‘-mtime +30′ option
    Feedback is welcome :-)

    Thanks again!!

  17. Melinda

    This post helped me tremendously; it didn’t provide my solution, but got me thinking in the right direction.

    I had fumble-fingered some keys in vi, and accidentally saved a file to “^?” which showed up under ls -la as a file with no name! I tried to isolate it by timestamp, but it was easier to use file size (which happened to be unique).

    Ultimately, this is the command that allowed me to recover the file:

    find /path/to/files/* -size 4246c -exec mv {} newname.pl \;

    I’ll have to remember the find command! Quite powerful! :)

  18. Pony

    Hello.

    I’m using a .php script to automatically perform full cPanel backups via cron job. It works quite nicely. However, space will become an issue real quick with these daily backups dumping into my root. I’m not using the ftp option to move them elsewhere at this time.

    I would like to set up a cron job in cPanel to automatically delete all cPanel backups that are 3 days old or older.

    Is this the correct command to do so or am I completely off base? If so, what is the correct command to work on cPanel 11 over Linux?

    find /home/user/backup-* -mtime +3 -exec rm {}\;

    The typical full backup reads like this /home/user/backup-2.4.2009_18-11-01_user.tar.gz I’m assuming the backup-* wildcard is correct usage as well.

    I would greatly appreciate it someone could point me in the write direction.

    Thanks.

  19. Melinda

    Pony,

    I wouldn’t consider myself an expert (since I just learned about this command recently), but it looks like the command you’ve constructed should do what you want.

    You could always create a test directory with some dummy files in it, and see if it works.

    Best wishes!

  20. Vince-0

    Frekin aye!

    Saved me some time – WHOOT for HowToGeek

  21. Buzzkill

    Pony,

    It looks like you are missing the space between {} and \ as explained in the directions.

  22. abdussamad

    regarding the -delete action:

    If you omit the * then you won’t get any errors and -delete will work

    find /path/to/files/ -mtime +5 -delete

  23. Pony

    I just wanted to say thanks for the feedback.

    I figured it out. Here is the Linux command I use on my Cron Job to auto delete all my cPanel backups that are 48 hours old or older. Everything is working great.

    find /home/username/ -name ‘backup-*’ -type f -ctime 1 -delete;

  24. larcin

    We currently are using this to delete files older than 60 days. “find installs/JS_* -maxdepth 0 -mtime +60 -type d -exec rm -rf {} \;”

    I was thinking that it would be better to set something up that would look at the the Newest file in the dir and then delete anything older than 60 days. Not sure where to start on that.

  25. josh

    I think my question’s already been answered but I want to make sure I understand this right:

    I have an FTP server for my firm. All the FTP directories sit at: /ftp/ftpsites/X/

    so if put a wildcard in for the X will that ignore the main FTP site but delete all the subdata? so /ftp/ftpsites/*/* -mtime +5 -exec rm {} \;

    I want it to save the parent directory, but that parent directory’s name will change depending on the FTP site.

    Thanks in advance for your help!

  26. Ahnolds

    Awesome command. I’d like to add that it works on macs as well (no surprise for a *nix based system). Solved the annoying problem of my downloads folder getting cluttered because it keeps *everything* I ever save :)

    Thanks

  27. Sir Hoagy

    How very cool this command showed up on “stumbleupon” when I just spoke with my friend today regarding reaping old files on our Linux server . We were going to have a cron command every Mon/Wed/Sat but this….THIS frickin’ is sweet! So much thanks!

  28. Matt Wells

    I run a script that takes the client’s URL and puts it into a file called database on my shared cPanel hosting. I want to empty that file once a day. What is the command line that I would enter into the advanced cron editor? I am probably wront but would it be something like:

    cp dev/null /home/username/public_html/directory/cgi-2009/database

    Please let me know..

    Thanks Much,

    Matt W.

  29. Offer

    Hi all,

    This is all great, but I still can’t figure something out…
    lets say I want to clean /tmp every day.
    Let us say file /tmp/dont_delete_me.txt is 7 days old. The process creating the file is still up and holding the file open. For this example let us say the process will write a single line every once in a while…
    If I would try to delete the file, what will happen to the holding process? Is there a way to know if a file is in use/open?

    I would like to clear a production server /tmp directory but never harm any running process…

    Thanks,
    Offer Baruch

  30. Artelius

    In response to Offer (re deleting files which are still open in some process)

    Under UNIX, the filesystem is like a “map” you use to locate files. Sometimes there are two different paths to the same file (these are called “hard links” and can be created with the ln command).

    When you “remove” a file, actually you are just removing one method of finding the file (this is why removing a file is sometimes called “unlinking”). When you remove ALL methods of finding a file, the file is really deleted and no longer takes up space.

    In your case, there are two links to the file:
    /tmp/dont_delete_me.txt
    and
    your program’s handle to this file

    If you remove the first of these, the file will not be deleted – it will still “exist” but will ONLY be accessible to the program that has the file open. When this program closes the file, the file disappears completely.

    Artelius

  31. spage

    Great tip. implemented this to clear stale mysql dumps.

    Offer… What about scheduling a cron to touch the file daily, weekly, or whatever? this will keep the file from aging and thus keep it from being deleted by this command?

  32. dennis

    a lot of smart people here … =)

    this tip and the comments help a lot.

  33. Philippe

    Artem Russakovskii and others, is there an argument for find, so that directories will NOT be removed?

    (From a NTFS slave-disc, I need to delete the 200 000 oldest and 50 000 newest files and only keep the directory tree and all files from a 20-day period. (Permission of NTFS files “cannot be decided”, so ownership is missing, which causes 250 000 questions “cannot move to trash, cancel/remove?” when I try using GNU desktop). (It is a “blue screen of death” disc of course…))

  34. Philippe

    Please remove my post, I discovered faults in it!


Leave a Comment




Leave your friendly comment here.

If you have a computer help question, click here to leave it on the forums instead.

Note: Your comment may not show up immediately on the site.

Our Friends
Getting Started


About How-To Geek
What Is That Process?
svchost.exe
jusched.exe
dwm.exe
ctfmon.exe
wmpnetwk.exe
wmpnscfg.exe
rundll32.exe
wfcrun32.exe
Ipoint.exe
Itype.exe
Wfica32.exe
Mobsync.exe
conhost.exe
Dpupdchk.exe Adobe_Updater.exe

Copyright © 2006-2009 HowToGeek.com. All Rights Reserved.