I have many movies in my hard drive and I have stored them in different folders based on the movie genre. Now, I want to keep only particular number of movie files in a directory, and delete everything else. More importantly, I want to delete only the oldest files. This way I can maintain a constant number of files in each folder. Since I have so many files scattered across many folders, it is quite time consuming process to go to each folder, search for the oldest files and manually delete them one by one. While looking for an easy way to do this, I found the following solution. Read on. It's not that difficult.
Find and delete oldest file in a directory in Linux
Let us say, you wanted to find and delete the oldest file if there are more than 10 files in a directory. How would you do? It's very simple.
Take the following directory named ostechnix as an example. Let us check how many files are in this directory using command:
$ find ostechnix/ -type f | wc -l
Or cd into that directory and run:
$ ls | wc -l
As you see in the above example, the directory ostechnix contains 33 files. I don't want 33 files in this directory. I want to delete all oldest files and keep only 10 files.
Now, let us find and delete oldest file(s) in this directory if it contains more than 10 files. To do so, go to that directory:
$ cd ostechnix
And, run the following command:
$ ls -1t | tail -n +11 | xargs rm
$ ls -1t | tail -n +11 | xargs rm -f
ls: List directory contents.
-1t: 1(Number one) indicates that the output of
lsshould be one file per line.
tindicates sort contents by modification time, newest first.
tail: Output the last part of files.
-n +11: output the last NUM lines, instead of the last 10; or use -n +NUM to output starting with line NUM
xargs: Build and execute command lines from standard input.
rm -f: Remove files or directories.
findicates ignore nonexistent files and arguments, never prompt. It means that this command won't display any error messages if there are less than 10 files.
|- It is a pipeline. It is generally a sequence of one or more commands separated by one of the control operators
So, the above command will delete the oldest files if there are more than 10 files in the current working directory. To verify how many files are in the directory after deleting the oldest file(s), just run:
$ ls | wc -l
If the filenames contains spaces, the above command will not work. Because, the
xargs command takes white space characters (tabs, spaces, new lines) as delimiters. In that case, you can narrow it down only for the new line characters (
-d option like below:
$ ls -1t | tail -n +11 | xargs -d '\n' rm -f
Hope this helps.
My files use spaces. How do I make it so “xargs rm -f” doesn’t treat each space as a separate filename?
Hey, sorry for the late reply. If your files contains spaces, use -d option like below.
ls -1t | tail -n +11 | xargs -d ‘\n’ rm -f
I have updated the guide now. Thanks for bringing it to my knowledge.
Hi! This is almost EXACTLY what I’ve been looking for, however, I need to delete all files but the last x from each sub-folder. I have a folder (BackupData) with many sub-folders (each folder is a different customers databackups), so I need the script to do a for-each sub-folder in BackupData, delete all files except most recent x
everyday I have a backup of some files. I need to delete files that are older then 30 days just if there are more then 20 files on that directory.
this will prevent deletion in case the backup has an issue and stop working.
I guess it will be require a condition IF right?
Instead of `tail -n +11` I think you could also use `head -10`
How to run this command from different directory but no the pwd
Could you please elaborate the question?
ls /your/directory -1t | tail -n +11 | xargs -d ‘\n’ rm -f