With zsh
:
rm -f -- *(.L0)
Would remove the regular (.
) non-hidden empty files (of L
ength 0).
In bash
or other shells:
zsh -c 'rm -f -- *(.L0)'
To remove files¹ whose name is made of only ASCII decimal digits:
rm -f <->
Where <->
is <x-y>
to match numbers in a range but with no bound. Again, with other shells, you can use zsh -c '...'
.
In bash
, you could also do:
(shopt -s extglob failglob; rm -f +([0123456789])
Or in ksh93
:
rm -f ~(N)+([0123456789])
You can combine the two (remove all-numeric empty regular files) with:
rm -f <->(.L0)
With the POSIX shell and utilities, the equivalent would be:
LC_ALL=C find . ! -name . -prune -type f -size 0c \
! -name '*[!0-9]*' -exec rm -f {} +
To find all-numeric files, we find all files except those that contain at least one non-digit. -size 0c
matches files whose size in bytes² is 0.
LC_ALL=C
makes sure the 0-9
range only includes 0123456789, but also and maybe more importantly for that command to work properly if there are filenames encoded in a charset different from that of the locale. For instance, without it, with GNU find
and in a UTF-8 locale, a file called $'St\xe9phane'
(Stéphane
encoded in latin1) would be deleted, not because non-digits can't be found in it (it's only made of non-digits), but because it contains that 0xe9 byte that can't be decoded into a character, so *
(which matches 0 or more characters) would fail to match.
zsh
globs don't have the problem, as bytes not forming part of characters are treated as some form of special characters, while with bash globs and with current versions, bash
switches to byte-wise matching when input strings can't be decoded into characters (making it behave as if in the C locale).
¹ this time not limited to regular files, also including symlinks, fifos... Files of type directory would not be deleted however as rm
won't delete directories unless you pass the -r
option.
² You could also use -size 0
(whose size in 512-byte units is 0), which would also work here as sizes are rounded up so a file of size one byte would be considered to be made of one 512-byte unit as far as -size 0
is concerned, but more generally, for exact size match, I would recommend using that c
suffix as -size 1
for instance is not for files of size 512, but for files of size 1 to 512. Use -size 512c
for files whose size is exactly 512. For zsh
's L
glob qualifier, the default unit is byte, not 512-byte unit.