find中的prune

根据man的说法,prune的作用就是不进入目录。

  1. find

find的简单用法是:

find [path] [expression]

expression主要由options,tests,actions三者组成,这三者又以operators分隔。
expression就是一个表达式,根据operators的优先级,按逻辑运算的方式从左到右执行。options和actions也有返回值,也是表达式中参与逻辑运算的一部分(之前的定式思维没有理解这一点)。

expression的默认operators是"与",即"-a",下面两条命令的含义是一样的:

find ./ -name "2020*" -type d
find ./ -name "2020*" -a -type d

operators的优先级从高到低依次为:
( expr )
! expr
expr1 -a expr2
expr1 -o expr2
expr1, expr2

  1. prune

-prune是一个actions,它的作用就是不进入目录(即target是目录时,不进入该目录,因此常常与-path一起出现),它本身返回true。

假设有如下目录:

./
./dir0
./dir0/a0.dat
./dir0/a1.txt
./dir0/dir0_0
./dir0/dir0_0/a2.dat
./dir0/dir0_0/a3.txt
./dir0/dir0_1
./dir0/dir0_1/a4.dat
./dir0/dir0_1/a5.txt
./dir1
./dir1/a6.dat
./dir1/a7.txt
./dir1/dir1_0
./dir1/dir1_0/a8.dat
./dir1/dir1_0/a9.txt
./f0.dat
./f1.txt

如果想查找所有的txt文件,但dir0目录下的除外,则可以用如下的命令:

find ./ -path "./dir0" -prune -o -name "*.txt" -print
./dir1/a7.txt
./dir1/dir1_0/a9.txt
./f1.txt

上述命令可以拆解为:
find ./ (expr1 and expr2) or (expr3 and expr4)
其中,
expr1: -path "./dir0"
expr2: -prune
expr3: -name "*.txt"
expr4: -print

执行时,如果遇到./dir0,则expr1返回true,继续执行expr2。expr2是-prune,它的返回值固定是ture,因此(expr1 and expr2)就返回true,or后面的语句不再执行(就不用判断dir0是不是txt,也不会将其打印出来)。整个expression的返回值是true。

注意,man find里有一句话:
If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.
意思是,如果整个expression为true,而且expression里面除了-prune这个action,就没有其他actions了,则将采用-print这个action,即执行打印动作。

遇到dir0时,虽然整个expression的返回值是true,但这个expression里除了-prune这个action,还有-print这个action(虽然没有执行到,但它确实存在),所以不满足描述的条件,因此也不会把dir0打印出来。

由于-prune的side effect是不进入目录,因此将不进入dir0,其下的所有文件都被跳过。

剩余的情况,expr1将返回false,因此(expr1 and expr2)也返回false,将执行(expr3 and expr4),即遇到txt文件将其打印出来。

  1. 更多用例

如果把上述用例中的-prune去掉,结果将是:

find ./ -path "./dir0" -o -name "*.txt" -print
./dir0/a1.txt
./dir0/dir0_0/a3.txt
./dir0/dir0_1/a5.txt
./dir1/a7.txt
./dir1/dir1_0/a9.txt
./f1.txt

即把所有的txt文件都找出来了,与find ./ -name "*.txt"没有差别。

执行时,遇到dir0,-path "./dir0"返回true,整个expression返回true(但不把dir0打印出来,见上面分析)。
会进入dir0目录查找其下的文件。
-path是严格匹配,因此dir0下的文件并不能让-path "./dir0"返回true,表达式的后半段-name "*.txt" -print也将被执行,即遇到txt文件打印出来。
剩余的情况,当然也是遇到txt文件打印出来。

如果把末尾的-print去掉,结果将是:

find ./ -path "./dir0" -prune -o -name "*.txt"
./dir0
./dir1/a7.txt
./dir1/dir1_0/a9.txt
./f1.txt

与原始的用例相比,把dir0打印出来了。

执行时,遇到dir0,-path "./dir0"返回true,整个expression返回true。由于整个expression除了-prune没有其他action了,将用-print作为默认的action,因此会把dir0打印出来。

不进入dir0,其下的所有文件都被跳过。

剩余的情况,遇到txt时,整个expression返回true,用-print作为默认的action,执行打印动作。

如果再随意改一下:

find ./ -path "./dir0" -o -name "*.txt" -prune -print
./dir0/a1.txt
./dir0/dir0_0/a3.txt
./dir0/dir0_1/a5.txt
./dir1/a7.txt
./dir1/dir1_0/a9.txt
./f1.txt

这个也是把所有的txt文件都找出来了,与find ./ -name "*.txt"没有差别。

执行时,遇到dir0,-path "./dir0"返回true,整个expression返回true(但不把dir0打印出来,见上面分析)。

会进入dir0目录查找其下的文件。表达式后面部分的-prune并没有在这里执行到,所以不能阻止进入dir0目录。
如果其他地方有一个目录名为aaa.txt,则表达式后面部分,会把aaa.txt打印出来,但不会进入aaa.txt查找其子目录和文件。


附带说明一下,find里的-name, -path等语句带的pattern,如果包含通配符(比如"*"),一般要把这个pattern用双引号包起来,否则通配符可能会被shell先解析到,导致结果与预期不符。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356