zoukankan      html  css  js  c++  java
  • find 忽略文件夹选项-prune的说明

    注意:因为习惯在当前路径查找时候,常忽略./ 的指定,但读者不要因此而完全忘记find的格式。

    查找时忽略指定目录,是要使用-prune选项,但实际上最重要的还是要和path配合。-prune的意义是,当路径字串匹配了path中指定的目录时 候,find命令不进入这个目录查找,所以这个选项使用的关键,还是在path选项上的使用,也就是path选项和其他选项的配合使用,才能最后确定最终 结果。而path,实际上是对路径字串的一个字符匹配,但也并不仅仅只匹配于目录,文件同样可以被匹配,譬如存在一个目录结构
    ./01.txt
    ./02.txt
    ./03.txt
    ./aaa
    ./aaa/04.txt
    ./aaa/05.txt

    find . -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选项。

  • 相关阅读:
    Struts2SpringHibernate整合示例,一个HelloWorld版的在线书店(项目源码+详尽注释+单元测试)
    Java实现蓝桥杯勇者斗恶龙
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 224 基本计算器
    Java实现 LeetCode 224 基本计算器
  • 原文地址:https://www.cnblogs.com/dawq/p/5777522.html
Copyright © 2011-2022 走看看