I have a folder which contains files (various file extensions) and subfolders. I want to keep certain file extensions and delete the rest.
e.g. keep all .txt and .jpg files and delete all other files.
on regular UNIX/GNU, I can use find together with the "-not" parameter to achieve this.
> find . -not -name "*.jpg" -not -name "*txt" -type f -delete
But sadly, this parameter is not available on busybox find.
Any ideas on how it can be done? Thanks a lot
Best Answer
-not
and-delete
are non-standard extensions.There's no reason why you'd want to use
-not
, when there's a shorter standard equivalent:!
.For
-delete
, you'll have to invokerm
with the-exec
predicate:(if you have an older version of busybox, you may need the
-exec rm -f '{}' ';'
which runs onerm
per file).That command above is standard, so will work not only in busybox but also with other non-GNU modern implementations of
find
.Note that on GNU systems at least, that command (with any
find
implementation as long as it uses GNUfnmatch(3)
) may still remove some files whose name ends in.jpg
or.txt
, as the*.jpg
pattern would fail to match files whose name contains invalid characters in the current locale.To work around that, you'd need:
Also note that contrary to GNU's
-delete
, that approach won't work in very deep directory trees as you would then end up reaching the maximum size of a file path passed to theunlink()
system call. AFAIK, withfind
, there's no way around that if yourfind
implementation doesn't support-execdir
nor-delete
.You may also want to read the security considerations discussed in the GNU
find
manual if you're going to run that command in a directory writable by others.