17

So, I got a directory filled with other directories, and I was wondering if it was possible to remove files that have no size. Typically these files are 0 bytes and since I want to merge all these subdirs I could replace a perfectly legit file with a weightless 0 byte file, and there goes my legit file. Any way to remove the zero byte files?

4 Answers 4

37

Use the Find command to find files by size and print file names to standard output.

find . -type f -size 0b -print

substitute -print with -delete to delete the files rather than print them on screen.

find . -type f -size 0b -delete
3
  • Now, is there any way to move files from one location to another, and with the conflicts replace if the size is the same but keep both copies if the size is different?
    – user245115
    Jun 7, 2015 at 19:02
  • This sounds like a job for rsync .
    – user257256
    Jun 7, 2015 at 19:07
  • 7
    You can use -empty instead of -size 0b.
    – Kevin
    Jun 8, 2015 at 4:57
6

Find and remove all files with a size of 0 recursively:

find . -type f -size 0 -print0 | xargs -I{} -0 rm {}

Example:

% ls -og   
total 4
-rw-rw-r-- 1 0 Jun  7 20:31 bar
-rw-rw-r-- 1 5 Jun  7 20:29 foo

% find . -size 0 -print0 | xargs -I{} -0 rm {}

% ls -og                                      
total 4
-rw-rw-r-- 1 5 Jun  7 20:29 foo
4

You can also do it directly in the shell. This could be useful if you don't want to delete empty hidden files (those whose name begins with a .). While you could do that with find as well, an alternative would be to use the shell itself:

shopt -s globstar
for file in **/*; do [ ! -s "$file" ] && [ -f "$file" ] && rm "$file"; done

Explanation

  • shopt -s globstar : turns on the globstar option for bash which makes ** match one or more subdirectories. **/* will match all files and directories in the current directory and all its subdirectories.
  • for file in **/*; do ...; done : iterate over all files and directories found;
  • [ ! -s "$file" ] : [ -s "$file" ] is true if the file exists and is not empty. Therefore, [ ! -s "$file" ] (the ! inverses the test) is true if the file doesn't exist or if it is empty.
  • [ -f "$file" ] : true if the file is a regular file. Not a directory or a device file or a symlink etc.
  • rm "$file" : delete the file.

The && ensure that the next command is only run if the previous one was successful so this will only delete empty, regular files.

1
  • 1
    and I thought, my answer is complicated :) +1
    – A.B.
    Jun 7, 2015 at 19:18
2

Although most answer above is correct, take a look for this command:

A 0 byte sized file means an empty file

though you can run this command:

find . -type f -empty -delete

this will delete all empty files.

You can take a look for those files before delete:

find . -type f -empty
1
  • On Ubuntu 14.04 LTS, without the -type f, -empty will also delete empty directories. Just checked the man page.
    – Bulrush
    Jul 30, 2015 at 17:53

You must log in to answer this question.

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