我需要删除所有编译数据:
- 名为 的目录
build
, - 名为 的目录
obj
, - *.so 文件。
我写了一个命令
find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;
它递归地遍历所有目录并删除我需要的所有内容。
为什么我最后会有这样的输出?也许我应该写一个不同的命令。
find: `./3/obj': No such file or directory
find: `./3/build': No such file or directory
find: `./1/obj': No such file or directory
find: `./1/build': No such file or directory
find: `./2/obj': No such file or directory
find: `./2/build': No such file or directory
答案1
-prune
在您要删除的目录上使用,告诉find
您不要费心尝试在其中查找文件:
find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} +
另请注意,*.so
需要加引号,否则 shell 可能会将其扩展到.so
当前目录中的文件列表。
GNU 类型的等价物-regex
是:
find . \( -name build -o -name obj -o -name '*?.so' \) -prune -exec rm -rf {} +
请注意,如果您要使用 GNU 特定语法,您不妨使用-delete
代替-exec rm -rf {} +
.使用 时-delete
,GNU将自动find
打开-depth
。它不运行外部命令,因此这样更高效,也更安全,因为它消除了竞争条件,在这种情况下,有人可能会通过将目录更改为符号链接来让您删除错误的文件find
找到一个文件并将rm
其删除(info -f find -n 'Security Considerations for find'
详细信息请参见)。
find . -regextype posix-egrep -regex '.*/((obj|build)(/.*)?|.+\.so)' -delete
答案2
我想原因是find
首先删除目录树并尝试检查目录内容,这显然不是最好的顺序。您可以find
先强制检查内容:
find . -depth ...
您应该考虑用于-delete
文件和-exec rmdir
目录。
答案3
我的解决方案。
find . -regextype posix-egrep -regex ".*/(obj|build|.+\.so)" -prune -exec rm -rf {} +