我想递归地删除该文件夹中一段时间未访问的a
所有文件,但子文件夹中的所有文件除外b
。
find a \( -name b -prune \) -o -type f -delete
但是,我收到一条错误消息:
查找:-delete操作自动打开-depth,但是当-depth有效时,-prune不执行任何操作。如果仍要继续,则只需显式使用-depth选项。
添加-depth
会导致b
其中包含所有文件,这一定不会发生。
任何人都知道一种安全的方法来完成这项工作吗?
一种方法是使用-exec rm
而不是-delete
。
find a \( -name b -prune \) -o -type f -exec rm {} +
或者使用-not -path
代替-prune
:
find a -not -path "*/b*" -type f -delete
解释为什么-prune
会与发生冲突-delete
:
当您尝试使用查找抱怨-delete
与-prune
因-delete
暗示-depth
而-depth
使得-prune
无效的。
观察使用和不使用find的行为-depth
:
$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2
不能保证单个目录中的订单。但是可以保证在目录内容之前先对其进行处理。注意foo/
之前foo/*
和foo/bar
之前foo/bar/*
。
可以用反转-depth
。
$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/
请注意,现在所有内容都foo/*
出现在之前foo/
。与相同foo/bar
。
更多说明:
-prune
防止查找下降到目录中。换句话说,-prune
跳过目录的内容。就您而言,这-name b -prune
意味着当find到达具有该名称的目录时b
,它将跳过该目录,包括所有子目录。-depth
可以在目录本身之前先处理目录的内容。这意味着,当find查找到处理目录条目时,b
其内容已被处理。因此-prune
实际上是无效的-depth
。-delete
意味着-depth
它可以先删除内容,然后删除空目录。-delete
拒绝删除非空目录。替代方法的说明:
find a -not -path "*/b*" -type f -delete
这可能容易记住,也可能不容易记住。
该命令仍然会进入目录b
并处理其中的每个文件,仅用于-not
拒绝它们。如果目录b
很大,这可能是性能问题。
-path
工作原理与有所不同-name
。-name
仅匹配(文件或目录的)名称,而-path
匹配整个路径。例如,观察路径/home/lesmana/foo/bar
。-name bar
将匹配,因为名称是bar
。-path "*/foo*"
将匹配,因为字符串/foo
在路径中。-path
使用前,您应该了解一些复杂的知识。阅读的手册页以find
获取更多详细信息。
请注意,这不是100%的万无一失。有可能出现“误报”。该命令上方的编写方式将跳过具有其父目录以b
(正)开头的任何父目录的文件。但是,b
无论树中的位置如何,它都将跳过名称以其开头的任何文件(误报)。可以通过编写一个比更好的表达式来解决此问题"*/b*"
。这留给读者作为练习。
我假设您使用a
和b
作为占位符,真实姓名更像allosaurus
和brachiosaurus
。如果您brachiosaurus
替换掉,b
那么误报的数量将大大减少。
至少不会误报,因此不会那么可悲。此外,您可以通过先不带命令运行命令来检查误报-delete
(但请记住放置隐含的-depth
)并检查输出。
find a -not -path "*/b*" -type f -depth
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句