注意:因?yàn)榱?xí)慣在當(dāng)前路徑查找時(shí)候,常忽略./ 的指定,但讀者不要因此而完全忘記find的格式。
查找時(shí)忽略指定目錄,是要使用-prune選項(xiàng),但實(shí)際上最重要的還是要和path配合。-prune的意義是,當(dāng)路徑字串匹配了path中指定的目錄時(shí)候,find命令不進(jìn)入這個(gè)目錄查找,所以這個(gè)選項(xiàng)使用的關(guān)鍵,還是在path選項(xiàng)上的使用,也就是path選項(xiàng)和其他選項(xiàng)的配合使用,才能最后確定最終結(jié)果。而path,實(shí)際上是對(duì)路徑字串的一個(gè)字符匹配,但也并不僅僅只匹配于目錄,文件同樣可以被匹配,譬如存在一個(gè)目錄結(jié)構(gòu)
./01.txt
./02.txt
./03.txt
./aaa
./aaa/04.txt
./aaa/05.txt
find . -path "./aaa*" -print
匹配中使用*通配符,則會(huì)輸出
./aaa
./aaa/04.txt
./aaa/05.txt
而如果是find . -path "./aaa" -print ,嚴(yán)格等于./aaa目錄,則只輸出
./aaa
而且*通配符會(huì)將路徑中的字符"/"也作為普通字符進(jìn)行貪婪匹配,所以可以匹配到目錄以下的文件,所以在使用這個(gè)選項(xiàng)時(shí)候不要誤以為這個(gè)只對(duì)目錄有效,實(shí)際上只是一種路徑字符匹配工具。
如果加上-prune,則第一個(gè)命令效果是:
find . -path "./aaa*" -prune -print
./aaa
因?yàn)榧尤肓?prune,在匹配這個(gè)目錄同時(shí)禁止進(jìn)入到這個(gè)目錄下搜索,于是也就是我們所需要的不進(jìn)入某個(gè)目錄查找。
但如何配合其他選項(xiàng)來(lái)使用-path 以及-prune呢?以-name為例,下面對(duì)于配合使用方法進(jìn)行一下演示。
我們先來(lái)看看純粹的-name和-path配合使用是什么效果:
find -name "*.txt" -path "./aaa" -print
這個(gè)命令也相當(dāng)于
find -name "*.txt" -a -path "./aaa"-print,但一般的-a都被忽略不寫(xiě)。這個(gè)命令對(duì)于上面的目錄結(jié)構(gòu)這個(gè)命令執(zhí)行為空結(jié)果。也就是,既要文件名稱(chēng)匹配"*.txt",同時(shí)又要其路徑字串匹配"./aaa",而文件名匹配"*.txt"的結(jié)果有:
./01.txt
./02.txt
./03.txt
./aaa/04.txt
./aaa/05.txt
路徑字串匹配 "./aaa"的只有
./aaa
二者取and則為空結(jié)果,所以上面的命令輸出為空。
如果對(duì)-path選項(xiàng)加上-prune,
find -name "*.txt" -path "./aaa" -prune -print
實(shí)際上與上面那條命令輸出并無(wú)區(qū)別,只是禁止進(jìn)入./aaa下匹配而已,但最終的結(jié)果仍然是空。
再來(lái)看看很多人會(huì)誤用的結(jié)構(gòu):
find -name "*.txt" -path "./aaa" -prune -o -print
也就是比上一條語(yǔ)句在-print前增加一個(gè)-o。但實(shí)際上這條命令是將當(dāng)前目錄以及包含./aaa子目錄下的所有文件都打印出來(lái)。實(shí)際上
,這個(gè)語(yǔ)句先執(zhí)行-o左側(cè)的語(yǔ)句,find -name "*.txt" -path "./aaa"-prune,因?yàn)槠ヅ錇榭?,則執(zhí)行-o右側(cè)的語(yǔ)句-print,也就是把不匹配左側(cè)的文件名打印出來(lái),既然左側(cè)沒(méi)有匹配為真的,所以也就是所有的文件都被打印。
這里要留意的是匹配模式項(xiàng)(比如-name "*.txt", -path ....),關(guān)系符( -a,-o, ","),與操作符(-print, -exec,-ok)之間的位置關(guān)系,特別是操作符在關(guān)系符的不同位置上,對(duì)于結(jié)果也具有決定的作用。
比如一個(gè)語(yǔ)句
find -name "*.txt" -print -o -path "./aaa" -prune-print (1)
其實(shí)也可以略寫(xiě)為
find -name "*.txt" -o -path "./aaa" -prune
注意第二個(gè)語(yǔ)句-o兩側(cè)都沒(méi)有-print,輸出結(jié)果為:
./01.txt
./02.txt
./03.txt
./aaa
這是因?yàn)閒ind開(kāi)始執(zhí)行,遇到第一個(gè)-print命令,則會(huì)考慮輸出,但是輸出的時(shí)候,則是將剩余所有的匹配項(xiàng)一起進(jìn)行匹配操作,也就是執(zhí)行的是
find -name "*.txt" -print -o -path "./aaa"-prune (注意-print命令的位置)
這個(gè)命令執(zhí)行中相當(dāng)于
find -path "./aaa" -prune -o -name "*.txt" -print
也就是在匹配過(guò)程中,對(duì)于包含了-print部分的匹配項(xiàng)是最后匹配的,因此先匹配到了./aaa路徑,由于-prune的存在禁止進(jìn)入這個(gè)路徑查找,禁止進(jìn)入查找,并不會(huì)因?yàn)?o選項(xiàng)而被逆轉(zhuǎn),所以左側(cè)匹配了./aaa后,-o右側(cè)則是不匹配./aaa項(xiàng)目剩余的文件繼續(xù)去匹配-name模式,匹配的結(jié)果最后被-print打印出來(lái),這也就是我們所期待的忽略某個(gè)指定目錄進(jìn)行搜索的結(jié)果。
但是我們要分析的是命令(1)中的結(jié)果,命令(1)在遇到第一個(gè)-print命令后并執(zhí)行了輸出,但是這個(gè)find命令中還存在第二個(gè)-print命令,所以在輸出
./01.txt
./02.txt
./03.txt
結(jié)果后,還是要繼續(xù)執(zhí)行,要執(zhí)行最后一個(gè)-print命令,下面的執(zhí)行則相當(dāng)于執(zhí)行一個(gè)
find -name "*.txt" -o -path "./aaa" -prune -print
-o左側(cè)匹配-name "*.txt",-o到右側(cè)后則是對(duì)不能匹配到-name模式的結(jié)果,進(jìn)行-path匹配,輸出結(jié)果為
./aaa
所以(1)命令最終的輸出結(jié)果就是
./01.txt
./02.txt
./03.txt
./aaa 。
-a, -o都常見(jiàn)了,但是實(shí)際中還可以存在“,“的使用,例如新建一個(gè)aaa1目錄,其下有08.txt等文件,若執(zhí)行
$ find -name "*.txt"
./01.txt
./02.txt
./03.txt
./aaa/04.txt
./aaa/05.txt
./aaa1/08.txt
./aaa1/09.txt
若忽略aaa和aaa1目錄查找txt文件,則可以寫(xiě)做
$ find -name "*.txt" -print -o -path "./aaa" -prune , -path"./aaa1" -prune (注意","兩側(cè)的空格不可忽略)
./01.txt
./02.txt
./03.txt
這也就是同時(shí)忽略幾個(gè)目錄的寫(xiě)法,注意每忽略一個(gè)目錄,其后都要跟隨一個(gè)-prune,而不能幾個(gè)-path公用一個(gè)-prune。
其實(shí)若沒(méi)有-prune的使用,也可以忽略某個(gè)目錄下文件的匹配,譬如
$find -path "./aaa*" -o -name "*.txt" -print
./01.txt
./02.txt
./03.txt
同樣可以不匹配到./aaa目錄下的文件,但是這里實(shí)際上是搜索過(guò)./aaa目錄下的文件并且進(jìn)行匹對(duì)的,只是因?yàn)?print在-o的右側(cè)輸出,而./aaa下的文件被匹配是在-o的左側(cè),所以最終的結(jié)果是達(dá)不到被打印輸出的條件。但效率應(yīng)當(dāng)是明顯低于使用-prune選項(xiàng)。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。