![在排除某些子路径的通配目录中查找文件](https://linux22.com/image/99372/%E5%9C%A8%E6%8E%92%E9%99%A4%E6%9F%90%E4%BA%9B%E5%AD%90%E8%B7%AF%E5%BE%84%E7%9A%84%E9%80%9A%E9%85%8D%E7%9B%AE%E5%BD%95%E4%B8%AD%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6.png)
考虑这个目录(和文件)结构:
mkdir testone
mkdir testtwo
mkdir testone/.svn
mkdir testtwo/.git
touch testone/fileA
touch testone/fileB
touch testone/fileC
touch testone/.svn/fileA1
touch testone/.svn/fileB1
touch testone/.svn/fileC1
touch testtwo/fileD
touch testtwo/fileE
touch testtwo/fileF
touch testtwo/.git/fileD1
touch testtwo/.git/fileE1
touch testtwo/.git/fileF1
我想打印/查找这两个目录中的所有文件,但不包括子目录.git
和/或.svn
.如果我这样做:
find test*
...然后所有文件都会被转储。
如果我这样做(例如,如何在通配符嵌入的“查找”搜索中排除/忽略隐藏文件和目录?):
$ find test* -path '.svn' -o -prune
testone
testtwo
$ find test* -path '*/.svn/*' -o -prune
testone
testtwo
...然后我只得到转储的顶级目录,而没有文件名。
是否可以find
单独使用来执行这样的搜索/列表,而不需要管道grep
(即find
对所有文件执行 a ,然后:find test* | grep -v '\.svn' | grep -v '\.git'
;这也会输出我不需要的顶级目录名称)?
答案1
您的find
命令没有说明如果给定路径不匹配该怎么办。如果您想排除以点开头的所有内容,并打印其余内容,请尝试:
find test* -path '*/.*' -prune -o -print
所以它会删除任何与该路径匹配的内容,并打印任何不匹配的内容。
输出示例:
testone
testone/fileC
testone/fileB
testone/fileA
testtwo
testtwo/fileE
testtwo/fileF
testtwo/fileD
如果您想专门排除以点开头的内容,但不排除其他内容,您可以执行以下操作.svn
:.git
find test* \( -path '*/.svn' -o -path '*/.git' \) -prune -o -print
对于这个例子产生相同的输出
如果你想排除顶级目录,你可以添加-mindepth 1
像
find test* -mindepth 1 -path '*/.*' -prune -o -print
这使
testone/fileC
testone/fileB
testone/fileA
testtwo/fileE
testtwo/fileF
testtwo/fileD
答案2
作为对 Eric 答案的补充,find
可以接受!
运算符来反转谓词。还有一个-wholename
测试将对文件(包括其路径)执行匹配。所以你可以写这样的东西:
find test* \( ! -wholename "*/.git/*" -a ! -wholename "*/.svn/*" \)