• 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选项。

  • 相关阅读:
    Leetcode: K-th Smallest in Lexicographical Order
    Leetcode: Minimum Number of Arrows to Burst Balloons
    Leetcode: Minimum Moves to Equal Array Elements
    Leetcode: Number of Boomerangs
    Leetcode: Arranging Coins
    Leetcode: Path Sum III
    Leetcode: All O`one Data Structure
    Leetcode: Find Right Interval
    Leetcode: Non-overlapping Intervals
    Socket网络编程--简单Web服务器(3)
  • 原文地址:https://www.cnblogs.com/dawq/p/5777522.html
Copyright © 2020-2023  润新知