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

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

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

e.g. keep all .txt and .jpg files and delete all other files.

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

> find . -not -name "*.jpg" -not -name "*txt" -type f -delete

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

关于如何做到这一点有什么想法吗?多谢

答案1

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

-not当有更短的标准等效项时,您没有理由要使用, !

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

find . ! -name '*.jpg' ! -name '*.txt' -type f -exec rm -f '{}' +

(如果您有旧版本的 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 '{}' +

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

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

答案2

忙碌盒find 索赔支持-regex选项,您可以使用它来删除文件做匹配模式:

find . -type f -regex '.*\.tmp\|.*\.core' -delete

不幸的是,在一般情况下,排除没有选项的扩展列表-not是不可能的(从技术上讲,有一个解决方案,但它无法扩展)。这就是-not首先包含该选项的原因。如果您需要排除任意扩展列表,则需要find支持此选项的扩展,或find+ grep+ xargs

find . | grep -v -e '\.jpg$' -e '\.txt$' | xargs rm

相关内容