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

时间: 2024-10-25 05:59:16

find 忽略文件夹选项-prune的说明的相关文章

.gitignore 规则写法 - 在已忽略文件夹中不忽略指定文件、文件夹【注意项】

1. 在已忽略文件夹中不忽略指定文件夹 /node_modules/* !/node_modules/layer/ 2. 在已忽略文件夹中不忽略指定文件 /node_modules/* !/node_modules/layer/layer.js [注意项]注意写法 要忽略的文件夹一定要结尾 /* ,否则不忽略规则将无法生效 3. 其他规则写法 (附) 以斜杠"/"开头表示目录: 以星号"*"通配多个字符: 以问号"?"通配单个字符 以方括号&qu

Win10电脑文件夹选项如何打开设置?

文件夹选项是Windows系统中非常重要的一个功能,在这里能对电脑内的文件及文件夹进行各种各样的设置以及操作.在Windows系统升级到Win10版本后,许多界面都发生了变化,文件夹选项也是如此,打开方式有些不同.那么在Win10系统中文件夹选项是怎么打开的呢?我们又该如何对其常用功能进行设置呢?下面就来告诉你. Win10系统文件夹选项怎么打开 1.打开我的电脑,点击上方菜单栏中的"查看"选项,就会出现一些设置选项.这里面都是一些常用的设置,是将原来版本的系统设置都划到了这里,比如图

Git远程忽略文件夹或文件

如果是文件夹使用递归的将文件夹忽略index git rm -r --cached 文件夹目录 如果是文件 git rm --cached 文件地址 提交 git commit -m "提交log说明" 推送到远程仓库 git push origin master

sublime 搜索时忽略文件夹

如上图:添加 "folder_exclude_patterns": ["要忽略的文件夹"]

TortoiseSVN忽略文件夹

因为平时要做一些主干.分支的版本控制,发布增量补丁包工作,所以经常使用TortoiseSVN客户端.当然,eclipse中也安装了SVN插件,不过在打补丁方面感觉不如客户端.现在遇到了一个问题:同一项目的副本,通过eclipse插件同步时会自动忽略整个classes文件夹,而客户端默认把文件夹及文件全部罗列出来了,强迫症发作了! 其实,本来是一件很简单的事情,但是我所用的1.8.6却不奏效,尝试之后用以下办法解决. 找到classes文件夹,加入版本控制(可能其他版本的客户端不需要这一步) 去除

IntelliJ IDEA 使用Subversion时忽略文件夹

IntelliJ IDEA 在使用Subversion进行版本管理时,忽略某个文件或者文件夹的操作方法如下: 1.选择Changes视图,点击如下图的图标(Configure Ignored Files). 2.在弹出的窗口中点击"+"号,在弹出的窗口选择要忽略的文件或文件夹. 3.点击OK,即可完成配置. 版权声明:本文为博主原创文章,未经博主允许不得转载.

Rsync忽略文件夹或目录

使用Rsync同步的时候往往会要求对某个文件夹或者文件进行忽略,客户端可以使用--exclude参数来实现对,目录或者文件的忽略 rsync -rltvz --port=873 --exclude ".svn" --exclude "Log" --progress --delete [email protected]::web /cygdrive/D/web/ 另外排除的文件及目录较多的情况还可以写到一个文件里: rsync -rltvz --port=873 --

WIN10桌面无创建文件夹选项,无法创建文件

在桌面或其他磁盘,右键没有新建选项,无法新建文件夹或文档.   右键桌面左下角开始按钮,点击:命令提示符(管理员)   弹出,Windows命令处理程序对话框,点击是   粘贴内容: cmd /k reg add "HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\New" /ve /t REG_SZ /d {D969A300-E7FF-11d0-A93B-00A0C90F2719} /f   点击键盘

Mac OS 文件夹选项配置文件.DS_Store批量替换与禁止生成

.DS_Store 是Mac OS Finder应用生成的文件夹视图配置 禁止生成.DS_Storedefaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE 允许生成.DS_Storedefaults delete com.apple.desktopservices DSDontWriteNetworkStores 批量删除.DS_Storesudo find / -name ".DS_Store&q