如何使用busybox find删除(或保留)某些文件扩展名?

mrj*_*per 4 find busybox

我有一个包含文件(各种文件扩展名)和子文件夹的文件夹。我想保留某些文件扩展名并删除其余的。

e.g. keep all .txt and .jpg files and delete all other files.
Run Code Online (Sandbox Code Playgroud)

在常规 UNIX/GNU 上,我可以将 find 与“-not”参数一起使用来实现此目的。

> find . -not -name "*.jpg" -not -name "*txt" -type f -delete
Run Code Online (Sandbox Code Playgroud)

但遗憾的是,这个参数在busybox find 上不可用。

关于如何做到这一点的任何想法?非常感谢

Sté*_*las 5

-not并且-delete是非标准扩展。

-not当有一个较短的标准等效项时,您没有理由想要使用!.

对于-delete,您必须rm使用-exec谓词进行调用:

find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '{}' +
Run Code Online (Sandbox Code Playgroud)

(如果你有一个旧版本的busybox,你可能需要每个文件-exec rm -f '{}' ';'运行一个rm)。

上面的命令是标准的,因此不仅可以在 busybox 中使用,而且可以在其他非 GNU 现代find.

请注意,至少在 GNU 系统上,该命令(find只要它使用 GNU 的任何实现fnmatch(3))可能仍会删除一些名称以.jpg或结尾的文件.txt,因为该*.jpg模式将无法匹配名称在当前语言环境中包含无效字符的文件。

要解决这个问题,您需要:

LC_ALL=C find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '{}' +
Run Code Online (Sandbox Code Playgroud)

另请注意,与 GNU 的 相反-delete,该方法在非常深的目录树中不起作用,因为您最终会达到传递给unlink()系统调用的文件路径的最大大小。AFAIK,find如果您的find实现不支持-execdir也不支持-delete.

如果您要在其他人可写的目录中运行该命令,您可能还需要阅读GNUfind手册中讨论安全注意事项