Deleting empty (zero-byte) files
Asked Answered
B

6

9

What's the easiest/best way to find and remove empty (zero-byte) files using only tools native to Mac OS X?

Boorer answered 13/2, 2009 at 1:45 Comment(3)
please clarify! one file that's empty, all empty files? what have you tried, what where the errors?Trunks
A comment to my answer clarified the question; updating appropriately.Sempstress
Thank you Charles Duffy. Sorry for my bad English :pBoorer
S
16

Easy enough:

find . -type f -size 0 -exec rm -f '{}' +

To ignore any file having xattr content (assuming the MacOS find implementation):

find . -type f -size 0 '!' -xattr -exec rm -f '{}' +

That said, note that many xattrs are not particularly useful (for example, com.apple.quarantine exists on all downloaded files).

Sempstress answered 13/2, 2009 at 1:50 Comment(12)
I use find . -size 0 -exec rm {} \; but add -type f should be betterBoorer
So, in English, "find all empty files in the current directory and delete them without prompting the user"?Perforated
So how would you do this recursively?Perforated
@Perforated - the command already given does recurse; you'd need to use an argument such as -maxdepth 1 to prevent it from doing so.Sempstress
@Bank, -exec rm {} \; is slower than -exec rm {} +, since it runs one each rm process per file to delete.Sempstress
Caution: this will delete .textClipping and other types of file that have data in extended attributes alone. See the example in post 3 under Trying to delete 0 byte files - The Lounge - TrueOS CommunityHoelscher
@GrahamPerrin, indeed -- a worthwhile notice for folks using any answer presently available on this question. Might you consider adding your own which avoids deleting files with nonempty xattrs?Sempstress
I'll try; it'll require help from someone with better knowledge, than me, on composing commands. I have someone in mind. Also please note that I am not testing pre-release APFS, so I can not tell whether utilities such as find and ls will behave, with APFS, as they do with HFS Plus with regard to not counting data in extended attributes and/or resource forks.Hoelscher
@GrahamPerrin, ...I'd expect them to comply with POSIX, and inasmuch as POSIX xattrs' size aren't counted in the file size returned by stat(), I would expect the tools to continue to reflect that so long as the standard requires them to.Sempstress
@GrahamPerrin, (by the way, if you can extract information about xattrs from find, I'd strongly suggest doing so: The output from ls can't be relied on for programmatic use; some of the output at the beginning of each line is well-specified, but that doesn't extend through the timestamp, much less the name).Sempstress
Anyhow -- once you have a proposal, feel free to @-notice me in for critique (and, hopefully, suggestions around robustness improvements). This is one of those cases where we want to be really careful around the corners -- if someone could get you to delete /etc/passwd via d=$'/tmp/ \n/etc/passwd\n/' mkdir -p -- "$d" && touch "$d/empty.txt" -- a class of fault many scripts relying on newlines to delimit filenames share -- that would be a comparably unfortunate bug.Sempstress
@CharlesDuffy in which of these rooms would you like to chat: /dev/chat, Ask Different Chat or Root Access? I suggest the former, as I might rope in someone else with knowledge of FreeBSD-based systems.Hoelscher
U
9

You can lower the potentially huge number of forks to run /bin/rm by:

find . -type f -size 0 -print0 | xargs -0 /bin/rm -f

The above command is very portable, running on most versions of Unix rather than just Linux boxes, and on versions of Unix going back for decades. For long file lists, several /bin/rm commands may be executed to keep the list from overrunning the command line length limit.

A similar effect can be achieved with less typing on more recent OSes, using a + in find to replace the most common use of xargs in a style still lends itself to other actions besides /bin/rm. In this case, find will handle splitting truly long file lists into separate /bin/rm commands. The {} is customarily quoted to keep the shell from doing anything to it; the quotes aren't always required but the intricacies of shell quoting are too involved to cover here, so when in doubt, include the apostrophes:

find . -type f -size 0 -exec /bin/rm -f '{}' +

In Linux, briefer approaches are usually available using -delete. Note that recent find's -delete primary is directly implemented with unlink(2) and doesn't spawn a zillion /bin/rm commands, or even the few that xargs and + do. Mac OS find also has the -delete and -empty primaries.

find . -type f -empty -delete

To stomp empty (and newly-emptied) files - directories as well - many modern Linux hosts can use this efficient approach:

find . -empty -delete
Ultraviolet answered 17/5, 2013 at 9:43 Comment(4)
This does improve portability, granted -- but find -exec ... {} + is available beyond only Linux. Immediately offhand, both Solaris 11 and OS X support this recent addition to the POSIX specification for find (added in issue 6 of 1003.1).Sempstress
The '+' syntax is less portable, but still pretty portable. It's definitely not available on a number of old Unixen that do have xargs. xargs is also much more flexible than the +, although the frequency of needing that extra flex is really low. I'll add the + form, though.Ultraviolet
@AlexNorth-Keys, ...but do those old-UNIX systems have xargs -0, or find -print0? If not, you have safety/correctness issues trying to do without.Sempstress
@CharlesDuffy Unix 7th and 8th editions apparently didn't have -print0 (or xargs, for that matter). In 1988, SunOS didn't have -print0 either, but does have xargs. So you're correct that old Unix systems aren't going to have them. IRIS 6.5's find(1) from 1998, no -print0. However, GNU find added -print0 in November 1990, so "decades" is still accurate, providing the GNU version of find was compiled locally.Ultraviolet
C
1
find /path/to/stuff -empty

If that's the list of files you're looking for then make the command:

find /path/to/stuff -empty -exec rm {} \;

Be careful! There won't be any way to undo this!

Couturier answered 13/2, 2009 at 1:49 Comment(1)
Better to use + than ; if you have a current find -- that way it acts the way xargs would if it were in the pipeline.Sempstress
W
1

Use:

find . -type f -size 0b -exec rm {} ';'

with all the other possible variations to limit what gets deleted.

Willmert answered 13/2, 2009 at 1:50 Comment(0)
C
0

A very simple solution in case you want to do it inside ONE particular folder:

  1. Go inside the folder, right click -> view -> as list.
  2. Now you'll find all the files listed as a list. Click on "Size" which must be a column heading. This will sort all the files based on it's size.
  3. Finally, you can find all the files that have zero bites at the last. Just select those and delete it!
Calebcaledonia answered 27/7, 2021 at 13:50 Comment(0)
W
0

No need for Terminal or command lines and text lists of files or piping to basically "program" the job.

It is as easy as 1,2,3 to use the native Finder "Find" for any file with the '.textclipping' extension that is 0 KB like this:

(note that you can also add file name matching but I did not to find all the 0KB clippings)

Finder list of zero byte text clippings

This is reported as a but to Apple under Feedback Assistant bug ID FB13702038.

It clobbered some of my 2002 (22 year old) clippings as well as some as new as 2021. Clipping age does not seem to be a factor.

This defect has been doing this for 10 years or more, but if we press as a community, perhaps we can get it fixed... Feedback Assistant... https://feedbackassistant.apple.com

Whisker answered 22/7 at 14:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.