注意:因为习惯在当前路径查找时候,常忽略./ 的指定,但读者不要因此而完全忘记find的格式。
查找时忽略指定目录,是要使用-prune选项,但实际上最重要的还是要和path配合。-prune的意义是,当路径字串匹配了path中指定的目录时 候,find命令不进入这个目录查找,所以这个选项使用的关键,还是在path选项上的使用,也就是path选项和其他选项的配合使用,才能最后确定最终 结果。而path,实际上是对路径字串的一个字符匹配,但也并不仅仅只匹配于目录,文件同样可以被匹配,譬如存在一个目录结构./01.txt./02.txt./03.txt./aaa./aaa/04.txt./aaa/05.txtfind . -path "./aaa*" -print 匹配中使用*通配符,则会输出./aaa./aaa/04.txt./aaa/05.txt而如果是find . -path "./aaa" -print ,严格等于./aaa目录,则只输出./aaa而且*通配符会将路径中的字符"/"也作为普通字符进行贪婪匹配,所以可以匹配到目录以下的文件,所以在使用这个选项时候不要误以为这个只对目录有效,实际上只是一种路径字符匹配工具。如果加上-prune,则第一个命令效果是:find . -path "./aaa*" -prune -print./aaa因为加入了-prune,在匹配这个目录同时禁止进入到这个目录下搜索,于是也就是我们所需要的不进入某个目录查找。但如何配合其他选项来使用-path 以及-prune呢?以-name为例,下面对于配合使用方法进行一下演示。我们先来看看纯粹的-name和-path配合使用是什么效果:find -name "*.txt" -path "./aaa" -print这个命令也相当于find -name "*.txt" -a -path "./aaa" -print,但一般的-a都被忽略不写。这个命令对于上面的目录结构这个命令执行为空结果。也就是,既要文件名称匹配"*.txt",同时又要其路径字 串匹配"./aaa",而文件名匹配"*.txt"的结果有:./01.txt./02.txt./03.txt./aaa/04.txt./aaa/05.txt路径字串匹配 "./aaa"的只有./aaa二者取and则为空结果,所以上面的命令输出为空。如果对-path选项加上-prune,find -name "*.txt" -path "./aaa" -prune -print实际上与上面那条命令输出并无区别,只是禁止进入./aaa下匹配而已,但最终的结果仍然是空。再来看看很多人会误用的结构:find -name "*.txt" -path "./aaa" -prune -o -print也就是比上一条语句在-print前增加一个-o。但实际上这条命令是将当前目录以及包含./aaa子目录下的所有文件都打印出来。实际上,这个语句先执行-o左侧的语句,find -name "*.txt" -path "./aaa" -prune,因为匹配为空,则执行-o右侧的语句-print,也就是把不匹配左侧的文件名打印出来,既然左侧没有匹配为真的,所以也就是所有的文件都被打印。这里要留意的是匹配模式项(比如-name "*.txt", -path ....),关系符( -a, -o, ","),与操作符(-print, -exec,- ok)之间的位置关系,特别是操作符在关系符的不同位置上,对于结果也具有决定的作用。比如一个语句find -name "*.txt" -print -o -path "./aaa" -prune -print (1)其实也可以略写为find -name "*.txt" -o -path "./aaa" -prune注意第二个语句-o两侧都没有-print,输出结果为:./01.txt./02.txt./03.txt./aaa 这是因为find开始执行,遇到第一个-print命令,则会考虑输出,但是输出的时候,则是将剩余所有的匹配项一起进行匹配操作,也就是执行的是find -name "*.txt" -print -o -path "./aaa" -prune (注意-print命令的位置)这个命令执行中相当于find -path "./aaa" -prune -o -name "*.txt" -print也 就是在匹配过程中,对于包含了-print部分的匹配项是最后匹配的,因此先匹配到了./aaa路径,由于-prune的存在禁止进入这个路径查找,禁止 进入查找,并不会因为-o选项而被逆转,所以左侧匹配了./aaa后,-o右侧则是不匹配./aaa项目剩余的文件继续去匹配-name模式,匹配的结果 最后被-print打印出来,这也就是我们所期待的忽略某个指定目录进行搜索的结果。但是我们要分析的是命令(1)中的结果,命令(1)在遇到第一个-print命令后并执行了输出,但是这个find命令中还存在第二个-print命令,所以在输出./01.txt./02.txt./03.txt结果后,还是要继续执行,要执行最后一个-print命令,下面的执行则相当于执行一个find -name "*.txt" -o -path "./aaa" -prune -print-o左侧匹配-name "*.txt",-o到右侧后则是对不能匹配到-name模式的结果,进行-path匹配,输出结果为./aaa所以(1)命令最终的输出结果就是./01.txt./02.txt./03.txt./aaa 。-a, -o都常见了,但是实际中还可以存在“,“的使用,例如新建一个aaa1目录,其下有08.txt等文件,若执行$ find -name "*.txt"./01.txt./02.txt./03.txt./aaa/04.txt./aaa/05.txt./aaa1/08.txt./aaa1/09.txt若忽略aaa和aaa1目录查找txt文件,则可以写做$ find -name "*.txt" -print -o -path "./aaa" -prune , -path "./aaa1" -prune (注意","两侧的空格不可忽略)./01.txt./02.txt./03.txt这也就是同时忽略几个目录的写法,注意每忽略一个目录,其后都要跟随一个-prune,而不能几个-path公用一个-prune。其实若没有-prune的使用,也可以忽略某个目录下文件的匹配,譬如$find -path "./aaa*" -o -name "*.txt" -print./01.txt./02.txt./03.txt同样可以不匹配到./aaa目录下的文件,但是这里实际上是搜索过./aaa目录下的文件并且进行匹对的,只是因为-print在-o的右侧输出,而./aaa下的文件被匹配是在-o的左侧,所以最终的结果是达不到被打印输出的条件。但效率应当是明显低于使用-prune选项。