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.

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


How about just using the -delete flag rather than the -exec ?
“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
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!
Now, can I pipe the results to a log file in the same line?
>>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.
there is an argument for find,so that also directory will be removed?
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.
Outstanding. Thanks for the help!!! This worked wonderfully!!!
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.
This seems to need user input to delete the files, what is the switch to have it delete automatically?
As mentioned, adding -f forces the delete.
find /path/to/files* -mtime +5 -exec rm -f {} \;
But when I run it, it still asks if I want to delete and I must type in a “y”
@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.
I had an issue like that with the cp command. Ended up that a previous admin had aliased the cp command to ‘cp -i’
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.
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!!
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!
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.
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!
Frekin aye!
Saved me some time – WHOOT for HowToGeek
Pony,
It looks like you are missing the space between {} and \ as explained in the directions.
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
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;
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.
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!
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
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!
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.
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
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
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?
a lot of smart people here … =)
this tip and the comments help a lot.
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…))
Please remove my post, I discovered faults in it!