Ubuntu – How to find all empty files and folders in a specific directory including files which just look empty but are not

command linedirectoryfilesscriptssearch

Let's say that in my folder ~/list I have a large amount of folders each with their own sub-folders and sub-sub-folders etc, and there are lots of files almost on each level. However some of these files and folders are empty, so how can I recursively search through them all to find the empty files and folders? And then have them displayed in a list of file locations so that I know where each one is (it should also be clear which is a file and which is a folder because not all files have file extensions). I am running Ubuntu GNOME 15.10 with GNOME 3.18.

Please note that it would also be very useful if it would also tell me if a file looked empty but wasn't (for instance if it had spaces or linebreaks in it or something). And would differentiate between a real empty file and one that just looks empty in the output.

Best Answer

From man find

    -empty File is empty and is either a regular file or a directory.

So to find both empty files and directories it is sufficient to do

find ~/lists -empty

To indicate the type, you could use the %y output format specifier

          %y     File's type (like in ls -l), U=unknown type (shouldn't happen)

e.g.

find ~/lists -empty -printf '%y %p\n'

or make use of an external program like ls, which includes a --classify option

    -F, --classify
          append indicator (one of */=>@|) to entries

i.e.

find ~/lists -empty -exec ls -Fd {} \;

If your definition of 'empty' is expanded to include files containing only whitespace characters, then it becomes more complicated - and more computationally intensive, since now you need to actually open at least any non-empty files and examine their contents. The most efficient way I can think of off the top of my head would be something like

find ~/list \( -empty -o \( -type f -a ! -exec grep -qm1 '[^[:blank:]]' {} \; \) \) -exec ls -Fd {} \;

(either empty, OR a file AND grep does not detect at least one non-blank character). Likely there is a better way though.