How do I recursively remove files that are less than 1MB in size from a directory?
Asked
Active
Viewed 2.6k times
5 Answers
25
This can be done with find:
find . -type f -size -1M -exec rm {} +
Note that this will recursively descend into subdirectories, and will unconditionally delete all files smaller than 1 megabyte. Be careful.
Sven Marnach
- 401
- 3
- 8
-
-
-
-
@Useless: It does, but other versions of `find` don't, so if you want portability, you should include a directory argument. – Sven Marnach Feb 08 '12 at 12:35
-
I would recommend `-delete` instead of `-exec rm`, since the latter will have corner-case problems with file names contaning weird characters (even newlines could appear), but mostly since it will die if the number of files is very large (>`getconf ARG_MAX`). This has happened to me when using `rm *` to clear a browser cache directory, and I think it applies in this case as well (if not, please feel free to tell me why). – Daniel Andersson Feb 13 '12 at 11:03
-
2@DanielAndersson: `find` restricts the number of arguments to the called process to fit into the system's limits, in contrast to `rm *`, which is guranteed to be a single process invocation. `find` will invoke multiple instance of `rm` if necessary. And I'm pretty sure that special characters are treated correctly, including newline characters. I prefer `-exec rm` over `-delete` for flexibility reasons -- as an example, the latter offers no way to delete write-protected files. – Sven Marnach Feb 13 '12 at 11:57
-
You are correct, and I thank you for your comment. `-exec +` takes ARG_MAX into account, and I have not seen any file name problems with `{}` in `find`. – Daniel Andersson Apr 04 '12 at 10:30
-
1@Invoker: I reverted your change since it was incorrect. `-1M` means less than one megabyte as desired. Your version would delete all files with exactly one megabyte in size, which seems to be a somewhat pointless operation. – Sven Marnach Oct 05 '15 at 15:28
-
2For anyone interested, if you want to remove all files _greater than_ 1M, use the command `find . -type f -size +1M -exec rm {} +`. Note the +1M instead of -1M. – chessofnerd Oct 06 '15 at 20:36
11
This should do the job:
$ find <directory> -type f -size -1M -delete
jcollado
- 266
- 1
- 6
-
-
3@Invoker, I believe the `-` sign is a minus sign meaning "less than 1M". If you run `find
-type f -size +1M -delete` you will delete all files _larger than_ 1M. – chessofnerd Oct 06 '15 at 20:10 -
2
Just for variety and a possible (probably marginal) performance gain:
find <directory> -type f -size -1M -print0 | xargs -0 rm
Useless
- 278
- 1
- 4
-
How is this supposed to be faster? It starts an additional `xargs` process. – Sven Marnach Feb 08 '12 at 12:33
-
Now you can have _two_ CPUs contending for the same block device! More sensibly, the stat/readdir operations aren't synchronously blocked by the unlink operation. Whether this is likely to be better obviously depends on the subtree size, number of files, device etc. – Feb 08 '12 at 12:36
1
Try
find . -size -1M -exec rm {} \;
ahvargas
- 111
- 2
-
1This is great for non-GNU users. Thanks! the same as @Sven's answer, but with `\;` at the end instead of `+` – hamx0r Aug 18 '16 at 18:16
-1
You can checkout this link http://ayaz.wordpress.com/2008/02/05/bash-quickly-deleting-empty-files-in-a-directory/ , it has exactly what you want.
for file in *;
do
file_size=$(du $file | awk '{print $1}');
if [ $file_size == 0 ]; then
echo "Deleting empty file $file with file size $file_size!";
echo "rm -f $file";
fi;
done
You can iterate through all the files with a for loop and then use du and awk to find the filesize like in the above example.
Steen Schütt
- 496
- 6
- 15
-
Answers on SO should be self-contained -- don't post a mere link. (Moreover, the code in the linked post deletes empty files rather than files smaller than 1M.) – Sven Marnach Feb 08 '12 at 12:32
-
-
-
-
1Well, if you test if this really works and copy the code to your answer, this might become an SO answer. – Sven Marnach Feb 08 '12 at 13:06