代碼1$ tree.|-- 2.log`-- backup `-- 1.log3 directories, 0 files代碼2$ find -path ./backup./backup代碼3$ mkdir backup123$ find -path ./backup*find: paths must PRecede expressionUsage: find [path...] [expression]find命令報錯:路徑必須先表達。問題分析(引自:http://www.CUOXin.com/baibaluo/archive/2012/08/16/2642403.html):
當目錄下存在多個backup*,shell命令變成find -path backup backup123.此時,-name后面有2個匹配字符,shell報錯。
解決辦法:-path(-name)匹配的字符串已經(jīng)要用單引號,或者雙引號引住。
代碼4$ find -path './backup*'./backup./backup/1.log./backup123此時,命令運行正確!
expr1 expr2 -o expr3 等同于 expr1 -a expr2 -o expr3.與其他語言中的與或非類似。并且是短路求值
代碼5$ find -path ./backup -name '*.log'$沒有任何返回結(jié)果。該語句的含義是:路徑是path,并且名字是以.log結(jié)尾的文件。顯然,并不存在。
本語句實際上是想查找,backup下所有的以.log結(jié)尾的文件。應(yīng)是:
find -path './backup*' -name '*.log'代碼6$ find -path './backup*' -o -name '*.log'./backup./backup/1.log./2.log./backup123到這個地方,-a 和 -o的體會已經(jīng)一目了然了吧。這條命令展示了在backup*下的所有文件和以.log結(jié)尾的所有文件。
-prune的體會貼上這樣的幾條shell命令,請先自行體會:
代碼7$ find -path './backup*'./backup./backup/1.log./backup123$ find -path './backup*' -prune./backup./backup123prune的基本使用-prune在man中是這么說的
If -depth is not given, true; do not descend the current directory.
If -depth is given, false; no effect.
如果find語句中存在-depth選項,那么-prune將會被忽略。否則,-prune將聲明不展開當前路徑。
這樣在上述的1、2條命令中,由于-prune選項的存在,致使backup路徑?jīng)]有展開。所以1.log沒有在打印列表中。
我們再次做這樣的嘗試:
代碼8$ touch backup123/3.log$ find -path './backup*' -prune./backup./backup123$ find -path './backup*'./backup./backup/1.log./backup123./backup123/3.log打印的結(jié)果和預(yù)期是一樣的。
按照上述2 find多條件中說道的那樣,find -path './backup*'獲得所有backup前綴的文件,然后將結(jié)果和-prune相與:其實就是判斷前者的結(jié)果中是否包含指定路徑的子文件(夾)。
prune做排除路徑用而一般情況下prune是這樣使用的
代碼9$ find -path './backup*' -prune -o -name '*.log' -print./2.log指代的意思是當前路徑除去backup*文件夾外的所有*.log文件。
這樣是如愿以償了,但是我們執(zhí)行一下這樣的一條命令:
代碼10$ find -path './backup*' -o -name '*.log' -print./2.log返回的結(jié)果一模一樣。
這個問題我們暫且擱置不論,繼續(xù)來看這樣的2個命令:
代碼11$ find -path './backup*' -prune -o -name '*.log'./backup./2.log./backup123$ find -path './backup*' -o -name '*.log'./backup./backup/1.log./2.log./backup1232個結(jié)果集中只是缺少了./backup/1.log,-prune做到的只是一個收縮路徑的功能。
再繼續(xù)對比這2個命令和上面兩個命令,缺少的是一個-print.其實在man里面有這樣的一句話"If no expression is given, the expression '-print' is used."
也就是說-print是個默認值,那么上面2組命令實際上可以這樣看待:
| 輸入命令 | 實際命令 |
|---|---|
find -path './backup*' -o -name '*.log' | find /( -path './backup*' -o -name '*.log' /) -print |
find -path './backup*' -o -name '*.log' -print | find /( -path './backup*' /) -o /( -name '*.log' -print /) |
代碼9 和 代碼10中的片段可以理解為打印-path './backup*'為false 、 -name '*.log' 為true的find結(jié)果。
而代碼11中的片段則是將-path './backup*' -o -name '*.log'過濾后所有為true的結(jié)果都打印。
那么這樣看來,其實排除路徑其實是將-print放置到了-o后面作為輸出。而-path './backup*'執(zhí)行過,并且返回true,單并未被打印。
那么是不是說,其實,其實,其實-prune并沒有什么用?
其實可以認為
試想這樣一個場景,在一個java項目中,由于項目龐大,總文件數(shù)上萬。想要找到最深2級目錄下所有的java文件。
find . -name "*.java" -maxdepth 2find . -maxdepth 2 -name "*.java"這樣的2條命令,顯然第二條的執(zhí)行效率會快!!!-maxdepth 2 極大程度的進行了一次結(jié)果過濾。
那么在寫find命令的時候,應(yīng)該把能最大程度減小結(jié)果集的結(jié)果放到前面。
新聞熱點
疑難解答